diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 85709e1d..da2cae3e 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -12,9 +12,9 @@ true MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol. -* [Client] Fixed issue in keep alive handling. -* [MQTTnet.Server] Added support for delivering static files (HTML, JavaScript etc.). -* [MQTTnet.Server] Fixed web socket protocol errors (when using paho JS etc.). +* [RcpClient] Adjusted some namespaces (BREAKING CHANGE!) +* [AspNetCore] Adjusted some namespaces (BREAKING CHANGE!) +* [Server] Adjusted some namespaces (BREAKING CHANGE!) Copyright Christian Kratky 2016-2020 MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin diff --git a/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs index 759b064d..d9e7ed81 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using MQTTnet.Server; -namespace MQTTnet.AspNetCore +namespace MQTTnet.AspNetCore.Extensions { public static class ApplicationBuilderExtensions { diff --git a/Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs index 262a333f..f62f8704 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Connections; -namespace MQTTnet.AspNetCore +namespace MQTTnet.AspNetCore.Extensions { public static class ConnectionBuilderExtensions { diff --git a/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs index d6749884..2736fce1 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs @@ -1,8 +1,11 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Connections; -using System; -namespace MQTTnet.AspNetCore +#if NETCOREAPP3_1 +using System; +#endif + +namespace MQTTnet.AspNetCore.Extensions { public static class ConnectionRouteBuilderExtensions { diff --git a/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs index d6ec5847..0560beae 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs @@ -5,7 +5,7 @@ using MQTTnet.Exceptions; using MQTTnet.Formatter; using MQTTnet.Packets; -namespace MQTTnet.AspNetCore +namespace MQTTnet.AspNetCore.Extensions { public static class ReaderExtensions { diff --git a/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs index 84a10d49..7ad53f4c 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs @@ -1,12 +1,12 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MQTTnet.Adapter; using MQTTnet.Diagnostics; using MQTTnet.Implementations; using MQTTnet.Server; -using System; -namespace MQTTnet.AspNetCore +namespace MQTTnet.AspNetCore.Extensions { public static class ServiceCollectionExtensions { diff --git a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs index 0b034c14..4aa0446a 100644 --- a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs +++ b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs @@ -10,6 +10,7 @@ using System.IO.Pipelines; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +using MQTTnet.AspNetCore.Extensions; namespace MQTTnet.AspNetCore { diff --git a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs index 58edcf8e..027346fc 100644 --- a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs +++ b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketBodyReader.cs @@ -8,9 +8,9 @@ namespace MQTTnet.AspNetCore { public class SpanBasedMqttPacketBodyReader : IMqttPacketBodyReader { - private ReadOnlyMemory _buffer; + ReadOnlyMemory _buffer; - private int _offset; + int _offset; public void SetBuffer(ReadOnlyMemory buffer) { @@ -38,16 +38,6 @@ namespace MQTTnet.AspNetCore { return ReadSegmentWithLengthPrefix().ToArray(); } - - private ReadOnlySpan ReadSegmentWithLengthPrefix() - { - var span = _buffer.Span; - var length = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(_offset)); - - var result = span.Slice(_offset+2, length); - _offset += 2 + length; - return result; - } public unsafe string ReadStringWithLengthPrefix() { @@ -121,5 +111,15 @@ namespace MQTTnet.AspNetCore { _offset = position; } + + ReadOnlySpan ReadSegmentWithLengthPrefix() + { + var span = _buffer.Span; + var length = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(_offset)); + + var result = span.Slice(_offset + 2, length); + _offset += 2 + length; + return result; + } } } diff --git a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketWriter.cs b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketWriter.cs index 66addfde..6043a618 100644 --- a/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketWriter.cs +++ b/Source/MQTTnet.AspnetCore/SpanBasedMqttPacketWriter.cs @@ -8,16 +8,10 @@ namespace MQTTnet.AspNetCore { public class SpanBasedMqttPacketWriter : IMqttPacketWriter { - private readonly ArrayPool _pool; + readonly ArrayPool _pool = ArrayPool.Create(); - public SpanBasedMqttPacketWriter() - { - _pool = ArrayPool.Create(); - - } - - private byte[] _buffer; - private int _position; + byte[] _buffer; + int _position; public int Length { get; set; } @@ -112,7 +106,7 @@ namespace MQTTnet.AspNetCore Commit(payload.Length); } - private void Commit(int count) + void Commit(int count) { if (_position == Length) { @@ -122,7 +116,7 @@ namespace MQTTnet.AspNetCore _position += count; } - private void GrowIfNeeded(int requiredAdditional) + void GrowIfNeeded(int requiredAdditional) { var requiredTotal = _position + requiredAdditional; if (_buffer.Length >= requiredTotal) diff --git a/Source/MQTTnet.Extensions.Rpc/Options/TopicGeneration/DefaultMqttRpcClientTopicGenerationStrategy.cs b/Source/MQTTnet.Extensions.Rpc/Options/TopicGeneration/DefaultMqttRpcClientTopicGenerationStrategy.cs index d38aa0b6..6d1f4bc7 100644 --- a/Source/MQTTnet.Extensions.Rpc/Options/TopicGeneration/DefaultMqttRpcClientTopicGenerationStrategy.cs +++ b/Source/MQTTnet.Extensions.Rpc/Options/TopicGeneration/DefaultMqttRpcClientTopicGenerationStrategy.cs @@ -1,7 +1,6 @@ -using MQTTnet.Extensions.Rpc.Options.TopicGeneration; -using System; +using System; -namespace MQTTnet.Extensions.Rpc.Options +namespace MQTTnet.Extensions.Rpc.Options.TopicGeneration { public class DefaultMqttRpcClientTopicGenerationStrategy : IMqttRpcClientTopicGenerationStrategy { diff --git a/Source/MQTTnet.Server/.config/dotnet-tools.json b/Source/MQTTnet.Server/.config/dotnet-tools.json new file mode 100644 index 00000000..1bbb1a45 --- /dev/null +++ b/Source/MQTTnet.Server/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "3.1.4", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/Source/MQTTnet.Server/MQTTnet.Server.csproj b/Source/MQTTnet.Server/MQTTnet.Server.csproj index 1603295e..8f2ac2ef 100644 --- a/Source/MQTTnet.Server/MQTTnet.Server.csproj +++ b/Source/MQTTnet.Server/MQTTnet.Server.csproj @@ -8,19 +8,22 @@ False MQTTnet - - + Standalone MQTT server with Python scripting backend. + The authors of MQTTnet.Server. false false latest - 1.0.0 + 3.0.11 3.3 MQTTnet.Server.Program c564f0de-28b4-45bf-b726-4d665d705653 + (c) Christian Kratky 2016-2020 + https://github.com/chkr1011/MQTTnet + https://github.com/chkr1011/MQTTnet diff --git a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs index 9bc9aca5..61982821 100644 --- a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs +++ b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs @@ -59,6 +59,7 @@ namespace MQTTnet.Adapter public async Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposed(); + cancellationToken.ThrowIfCancellationRequested(); try { @@ -85,6 +86,7 @@ namespace MQTTnet.Adapter public async Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposed(); + cancellationToken.ThrowIfCancellationRequested(); try { @@ -112,8 +114,17 @@ namespace MQTTnet.Adapter public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposed(); + cancellationToken.ThrowIfCancellationRequested(); + + try + { + await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + } + catch (ObjectDisposedException) + { + throw new OperationCanceledException(); + } - await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { var packetData = PacketFormatterAdapter.Encode(packet); @@ -144,13 +155,22 @@ namespace MQTTnet.Adapter finally { PacketFormatterAdapter.FreeBuffer(); - _writerSemaphore?.Release(); + + try + { + _writerSemaphore.Release(); + } + catch (ObjectDisposedException) + { + throw new OperationCanceledException(); + } } } public async Task ReceivePacketAsync(TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposed(); + cancellationToken.ThrowIfCancellationRequested(); try { @@ -189,6 +209,9 @@ namespace MQTTnet.Adapter catch (OperationCanceledException) { } + catch (ObjectDisposedException) + { + } catch (Exception exception) { if (IsWrappedException(exception)) @@ -212,8 +235,8 @@ namespace MQTTnet.Adapter { if (disposing) { - _channel?.Dispose(); - _writerSemaphore?.Dispose(); + _channel.Dispose(); + _writerSemaphore.Dispose(); } base.Dispose(disposing); diff --git a/Source/MQTTnet/Implementations/CrossPlatformSocket.cs b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs index 2b3bed2f..8d80b1a9 100644 --- a/Source/MQTTnet/Implementations/CrossPlatformSocket.cs +++ b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs @@ -20,7 +20,7 @@ namespace MQTTnet.Implementations public CrossPlatformSocket() { - // Having this contructor is important because avoiding the address family as parameter + // Having this constructor is important because avoiding the address family as parameter // will make use of dual mode in the .net framework. _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); } @@ -33,75 +33,34 @@ namespace MQTTnet.Implementations public bool NoDelay { - get - { - return (int)_socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) > 0; - } - - set - { - _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0); - } + get => (int)_socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) > 0; + set => _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0); } public bool DualMode { - get - { - return _socket.DualMode; - } - - set - { - _socket.DualMode = value; - } + get => _socket.DualMode; + set => _socket.DualMode = value; } public int ReceiveBufferSize { - get - { - return _socket.ReceiveBufferSize; - } - - set - { - _socket.ReceiveBufferSize = value; - } + get => _socket.ReceiveBufferSize; + set => _socket.ReceiveBufferSize = value; } public int SendBufferSize { - get - { - return _socket.SendBufferSize; - } - - set - { - _socket.SendBufferSize = value; - } + get => _socket.SendBufferSize; + set => _socket.SendBufferSize = value; } - public EndPoint RemoteEndPoint - { - get - { - return _socket.RemoteEndPoint; - } - } + public EndPoint RemoteEndPoint => _socket.RemoteEndPoint; public bool ReuseAddress { - get - { - return (int)_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress) != 0; - } - - set - { - _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, value ? 1 : 0); - } + get => (int)_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress) != 0; + set => _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, value ? 1 : 0); } public async Task AcceptAsync() diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs index fde169b8..ce224057 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs @@ -17,14 +17,14 @@ using MQTTnet.Server; namespace MQTTnet.Implementations { - public class MqttTcpChannel : IMqttChannel + public sealed class MqttTcpChannel : IMqttChannel { - private readonly MqttClientTcpOptions _options; - private readonly int _bufferSize; + readonly MqttClientTcpOptions _options; + readonly int _bufferSize; - private StreamSocket _socket; - private Stream _readStream; - private Stream _writeStream; + StreamSocket _socket; + Stream _readStream; + Stream _writeStream; public MqttTcpChannel(IMqttClientOptions clientOptions) { diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 5f95e72f..19ec6d1e 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; namespace MQTTnet.Implementations { - public sealed class MqttTcpChannel : IDisposable, IMqttChannel + public sealed class MqttTcpChannel : IMqttChannel { readonly IMqttClientOptions _clientOptions; readonly MqttClientTcpOptions _options; @@ -162,7 +162,6 @@ namespace MQTTnet.Implementations } catch (ObjectDisposedException) { - return; } catch (IOException exception) { @@ -205,7 +204,6 @@ namespace MQTTnet.Implementations { return certificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions); } - #endregion var certificateValidationHandler = _options?.TlsOptions?.CertificateValidationHandler; @@ -229,7 +227,7 @@ namespace MQTTnet.Implementations if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.OfflineRevocation)) { - if (!_options.TlsOptions.IgnoreCertificateRevocationErrors) + if (_options?.TlsOptions?.IgnoreCertificateRevocationErrors != true) { return false; } @@ -237,13 +235,13 @@ namespace MQTTnet.Implementations if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.PartialChain)) { - if (!_options.TlsOptions.IgnoreCertificateChainErrors) + if (_options?.TlsOptions?.IgnoreCertificateChainErrors != true) { return false; } } - return _options.TlsOptions.AllowUntrustedCertificates; + return _options?.TlsOptions?.AllowUntrustedCertificates == true; } X509CertificateCollection LoadCertificates() diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs index fb6d5a3f..f95801fb 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs @@ -130,7 +130,7 @@ namespace MQTTnet.Implementations } } - private Task OnClientAcceptedAsync(IMqttChannelAdapter channelAdapter) + Task OnClientAcceptedAsync(IMqttChannelAdapter channelAdapter) { var clientHandler = ClientHandler; if (clientHandler == null) diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs index 00e19a1a..8e54c78a 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs @@ -24,8 +24,8 @@ namespace MQTTnet.Implementations readonly MqttServerTlsTcpEndpointOptions _tlsOptions; readonly X509Certificate2 _tlsCertificate; - private CrossPlatformSocket _socket; - private IPEndPoint _localEndPoint; + CrossPlatformSocket _socket; + IPEndPoint _localEndPoint; public MqttTcpServerListener( AddressFamily addressFamily, diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs index e69db2c3..70871e4d 100644 --- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs +++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs @@ -35,7 +35,7 @@ namespace MQTTnet.Implementations public bool IsSecureConnection { get; private set; } - public X509Certificate2 ClientCertificate { get; private set; } + public X509Certificate2 ClientCertificate { get; } public async Task ConnectAsync(CancellationToken cancellationToken) { diff --git a/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs b/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs index 3f5fe0ea..acaff874 100644 --- a/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs +++ b/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs @@ -1,4 +1,7 @@ -public interface IMqttServerCertificateCredentials +namespace MQTTnet.Server { - string Password { get; } + public interface IMqttServerCertificateCredentials + { + string Password { get; } + } } diff --git a/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj b/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj index 8442b20a..4a7526b8 100644 --- a/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj +++ b/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj @@ -6,13 +6,15 @@ - - + + + + diff --git a/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs b/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs index e76d6274..2b5bf473 100644 --- a/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs +++ b/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs @@ -15,6 +15,7 @@ using MQTTnet.Exceptions; using MQTTnet.Formatter; using MQTTnet.Packets; using System.Net; +using MQTTnet.AspNetCore.Extensions; namespace MQTTnet.AspNetCore.Tests { diff --git a/Tests/MQTTnet.AspNetCore.Tests/ReaderExtensionsTest.cs b/Tests/MQTTnet.AspNetCore.Tests/ReaderExtensionsTest.cs index f08f57df..a98e98ed 100644 --- a/Tests/MQTTnet.AspNetCore.Tests/ReaderExtensionsTest.cs +++ b/Tests/MQTTnet.AspNetCore.Tests/ReaderExtensionsTest.cs @@ -1,6 +1,7 @@ -#if NETCOREAPP +#if NETCOREAPP3_1 using System.Buffers; using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.AspNetCore.Extensions; using MQTTnet.Formatter; using MQTTnet.Packets; @@ -31,7 +32,6 @@ namespace MQTTnet.AspNetCore.Tests result = serializer.TryDecode(reader, part, out packet, out consumed, out observed, out read); Assert.IsFalse(result); - part = sequence.Slice(sequence.Start, 1); // partial fixed header should fail result = serializer.TryDecode(reader, part, out packet, out consumed, out observed, out read); Assert.IsFalse(result); diff --git a/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs b/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs index 87ec1348..d14f7f44 100644 --- a/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs +++ b/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting; using MQTTnet.Server; using MQTTnet.Diagnostics; using MQTTnet.AspNetCore.Client; +using MQTTnet.AspNetCore.Extensions; using MQTTnet.Client.Options; namespace MQTTnet.Benchmarks diff --git a/Tests/MQTTnet.Core.Tests/Server_Tests.cs b/Tests/MQTTnet.Core.Tests/Server_Tests.cs index 271ea9cf..18c106d7 100644 --- a/Tests/MQTTnet.Core.Tests/Server_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/Server_Tests.cs @@ -274,6 +274,78 @@ namespace MQTTnet.Tests } } + [TestMethod] + public async Task Subscribe_Lots_In_Single_Request() + { + using (var testEnvironment = new TestEnvironment(TestContext)) + { + var receivedMessagesCount = 0; + + await testEnvironment.StartServerAsync(); + + var c1 = await testEnvironment.ConnectClientAsync(); + c1.UseApplicationMessageReceivedHandler(c => Interlocked.Increment(ref receivedMessagesCount)); + + var optionsBuilder = new MqttClientSubscribeOptionsBuilder(); + for (var i = 0; i < 1000; i++) + { + optionsBuilder.WithTopicFilter(i.ToString(), MqttQualityOfServiceLevel.AtMostOnce); + } + + await c1.SubscribeAsync(optionsBuilder.Build()).ConfigureAwait(false); + + var c2 = await testEnvironment.ConnectClientAsync(); + + var messageBuilder = new MqttApplicationMessageBuilder(); + for (var i = 0; i < 1000; i++) + { + messageBuilder.WithTopic(i.ToString()); + + await c2.PublishAsync(messageBuilder.Build()).ConfigureAwait(false); + } + + await Task.Delay(500).ConfigureAwait(false); + + Assert.AreEqual(1000, receivedMessagesCount); + } + } + + [TestMethod] + public async Task Subscribe_Lots_In_Multiple_Requests() + { + using (var testEnvironment = new TestEnvironment(TestContext)) + { + var receivedMessagesCount = 0; + + await testEnvironment.StartServerAsync(); + + var c1 = await testEnvironment.ConnectClientAsync(); + c1.UseApplicationMessageReceivedHandler(c => Interlocked.Increment(ref receivedMessagesCount)); + + for (var i = 0; i < 1000; i++) + { + var so = new MqttClientSubscribeOptionsBuilder() + .WithTopicFilter(i.ToString(), MqttQualityOfServiceLevel.AtMostOnce).Build(); + + await c1.SubscribeAsync(so).ConfigureAwait(false); + } + + var c2 = await testEnvironment.ConnectClientAsync(); + + var messageBuilder = new MqttApplicationMessageBuilder(); + for (var i = 0; i < 1000; i++) + { + messageBuilder.WithTopic(i.ToString()); + + await c2.PublishAsync(messageBuilder.Build()).ConfigureAwait(false); + } + + await Task.Delay(500).ConfigureAwait(false); + + Assert.AreEqual(1000, receivedMessagesCount); + } + } + [TestMethod] public async Task Subscribe_Multiple_In_Multiple_Request() { diff --git a/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs b/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs index aed19b43..1f65f7a4 100644 --- a/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs +++ b/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting; using MQTTnet.AspNetCore; using System.Threading.Tasks; +using MQTTnet.AspNetCore.Extensions; namespace MQTTnet.TestApp.AspNetCore2 { diff --git a/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs b/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs index 0965f0d2..9a240f52 100644 --- a/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs +++ b/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; using MQTTnet.AspNetCore; +using MQTTnet.AspNetCore.Extensions; using MQTTnet.Server; namespace MQTTnet.TestApp.AspNetCore2