From 9ed80daf83f03634804ab57705c635d4461ebf4f Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Wed, 25 Mar 2020 21:32:43 +0800 Subject: [PATCH 1/4] Reduce the performance cost of Memory.getSpan() --- Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs index 2746c7d..d6ec584 100644 --- a/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs @@ -80,7 +80,7 @@ namespace MQTTnet.AspNetCore headerLength = 0; bodyLength = 0; - var temp = input.Slice(0, Math.Min(5, input.Length)).GetMemory(); + var temp = input.Slice(0, Math.Min(5, input.Length)).GetMemory().Span; do { @@ -88,7 +88,7 @@ namespace MQTTnet.AspNetCore { return false; } - encodedByte = temp.Span[index]; + encodedByte = temp[index]; index++; value += (byte)(encodedByte & 127) * multiplier; From 561474c5723383866b6e1388d38826b9c292d761 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Thu, 26 Mar 2020 15:35:14 +0100 Subject: [PATCH 2/4] Fix broken unit tests. --- Build/MQTTnet.nuspec | 1 + .../MQTTnet.AspNetCore.csproj | 6 +- Source/MQTTnet/Adapter/MqttChannelAdapter.cs | 66 ++++++++++--------- .../PacketDispatcher/MqttPacketAwaiter.cs | 11 ++-- Source/MQTTnet/Server/MqttClientConnection.cs | 13 ++-- .../ManagedMqttClient_Tests.cs | 14 ++-- Tests/MQTTnet.Core.Tests/MqttFactory_Tests.cs | 48 +++++++------- 7 files changed, 84 insertions(+), 75 deletions(-) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index fd8614e..a6e7faf 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -11,6 +11,7 @@ false 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. +* [All] Due to a merge issue not all changes are included in 3.0.8. All these changes are now included in this version. * [ManagedClient] Added builder class for MqttClientUnsubscribeOptions (thanks to @dominikviererbe). * [ManagedClient] Added support for persisted sessions (thansk to @PMExtra). * [Client] Improve connection stability (thanks to @jltjohanlindqvist). diff --git a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj index c0768b4..e6f0582 100644 --- a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj +++ b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj @@ -14,11 +14,13 @@ RELEASE;NETSTANDARD2_0 - + + + - + diff --git a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs index d7585cb..ccf5a33 100644 --- a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs +++ b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs @@ -1,3 +1,9 @@ +using MQTTnet.Channel; +using MQTTnet.Diagnostics; +using MQTTnet.Exceptions; +using MQTTnet.Formatter; +using MQTTnet.Internal; +using MQTTnet.Packets; using System; using System.IO; using System.Net.Sockets; @@ -5,30 +11,24 @@ using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; -using MQTTnet.Channel; -using MQTTnet.Diagnostics; -using MQTTnet.Exceptions; -using MQTTnet.Formatter; -using MQTTnet.Internal; -using MQTTnet.Packets; namespace MQTTnet.Adapter { public class MqttChannelAdapter : Disposable, IMqttChannelAdapter { - private const uint ErrorOperationAborted = 0x800703E3; - private const int ReadBufferSize = 4096; // TODO: Move buffer size to config + const uint ErrorOperationAborted = 0x800703E3; + const int ReadBufferSize = 4096; // TODO: Move buffer size to config - private readonly SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1); + readonly IMqttNetChildLogger _logger; + readonly IMqttChannel _channel; + readonly MqttPacketReader _packetReader; - private readonly IMqttNetChildLogger _logger; - private readonly IMqttChannel _channel; - private readonly MqttPacketReader _packetReader; + readonly byte[] _fixedHeaderBuffer = new byte[2]; - private readonly byte[] _fixedHeaderBuffer = new byte[2]; - - private long _bytesReceived; - private long _bytesSent; + SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1); + + long _bytesReceived; + long _bytesSent; public MqttChannelAdapter(IMqttChannel channel, MqttPacketFormatterAdapter packetFormatterAdapter, IMqttNetChildLogger logger) { @@ -55,7 +55,7 @@ namespace MQTTnet.Adapter public Action ReadingPacketStartedCallback { get; set; } public Action ReadingPacketCompletedCallback { get; set; } - + public async Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposed(); @@ -143,7 +143,7 @@ namespace MQTTnet.Adapter } finally { - _writerSemaphore.Release(); + _writerSemaphore?.Release(); } } @@ -207,7 +207,20 @@ namespace MQTTnet.Adapter Interlocked.Exchange(ref _bytesSent, 0L); } - private async Task ReceiveAsync(CancellationToken cancellationToken) + protected override void Dispose(bool disposing) + { + if (disposing) + { + _channel?.Dispose(); + + _writerSemaphore?.Dispose(); + _writerSemaphore = null; + } + + base.Dispose(disposing); + } + + async Task ReceiveAsync(CancellationToken cancellationToken) { var readFixedHeaderResult = await _packetReader.ReadFixedHeaderAsync(_fixedHeaderBuffer, cancellationToken).ConfigureAwait(false); @@ -267,25 +280,14 @@ namespace MQTTnet.Adapter } } - protected override void Dispose(bool disposing) - { - if (disposing) - { - _channel?.Dispose(); - _writerSemaphore?.Dispose(); - } - - base.Dispose(disposing); - } - - private static bool IsWrappedException(Exception exception) + static bool IsWrappedException(Exception exception) { return exception is OperationCanceledException || exception is MqttCommunicationTimedOutException || exception is MqttCommunicationException; } - private static void WrapException(Exception exception) + static void WrapException(Exception exception) { if (exception is IOException && exception.InnerException is SocketException innerException) { diff --git a/Source/MQTTnet/PacketDispatcher/MqttPacketAwaiter.cs b/Source/MQTTnet/PacketDispatcher/MqttPacketAwaiter.cs index b172290..d8f0a04 100644 --- a/Source/MQTTnet/PacketDispatcher/MqttPacketAwaiter.cs +++ b/Source/MQTTnet/PacketDispatcher/MqttPacketAwaiter.cs @@ -1,9 +1,9 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using MQTTnet.Exceptions; +using MQTTnet.Exceptions; using MQTTnet.Internal; using MQTTnet.Packets; +using System; +using System.Threading; +using System.Threading.Tasks; namespace MQTTnet.PacketDispatcher { @@ -12,7 +12,7 @@ namespace MQTTnet.PacketDispatcher private readonly TaskCompletionSource _taskCompletionSource; private readonly ushort? _packetIdentifier; private readonly MqttPacketDispatcher _owningPacketDispatcher; - + public MqttPacketAwaiter(ushort? packetIdentifier, MqttPacketDispatcher owningPacketDispatcher) { _packetIdentifier = packetIdentifier; @@ -87,6 +87,7 @@ namespace MQTTnet.PacketDispatcher { _owningPacketDispatcher.RemovePacketAwaiter(_packetIdentifier); } + base.Dispose(disposing); } } diff --git a/Source/MQTTnet/Server/MqttClientConnection.cs b/Source/MQTTnet/Server/MqttClientConnection.cs index c9e2553..5528969 100644 --- a/Source/MQTTnet/Server/MqttClientConnection.cs +++ b/Source/MQTTnet/Server/MqttClientConnection.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using MQTTnet.Adapter; +using MQTTnet.Adapter; using MQTTnet.Client; using MQTTnet.Diagnostics; using MQTTnet.Exceptions; @@ -12,6 +8,10 @@ using MQTTnet.PacketDispatcher; using MQTTnet.Packets; using MQTTnet.Protocol; using MQTTnet.Server.Status; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MQTTnet.Server { @@ -437,9 +437,8 @@ namespace MQTTnet.Server { _logger.Warning(exception, "Sending publish packet failed: Communication exception (ClientId: {0}).", ClientId); } - else if (exception is OperationCanceledException && _cancellationToken.Token.IsCancellationRequested) + else if (exception is OperationCanceledException) { - // The cancellation was triggered externally. } else { diff --git a/Tests/MQTTnet.Core.Tests/ManagedMqttClient_Tests.cs b/Tests/MQTTnet.Core.Tests/ManagedMqttClient_Tests.cs index edfe058..52ec583 100644 --- a/Tests/MQTTnet.Core.Tests/ManagedMqttClient_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/ManagedMqttClient_Tests.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MQTTnet.Client; using MQTTnet.Client.Connecting; using MQTTnet.Client.Options; @@ -12,6 +7,11 @@ using MQTTnet.Diagnostics; using MQTTnet.Extensions.ManagedClient; using MQTTnet.Server; using MQTTnet.Tests.Mockups; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace MQTTnet.Tests { @@ -110,6 +110,8 @@ namespace MQTTnet.Tests await managedClient.StopAsync(); + await Task.Delay(500); + Assert.AreEqual(0, (await server.GetClientStatusAsync()).Count); } } diff --git a/Tests/MQTTnet.Core.Tests/MqttFactory_Tests.cs b/Tests/MQTTnet.Core.Tests/MqttFactory_Tests.cs index eb7aba3..740980d 100644 --- a/Tests/MQTTnet.Core.Tests/MqttFactory_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/MqttFactory_Tests.cs @@ -15,35 +15,38 @@ namespace MQTTnet.Tests { var factory = new MqttFactory(); - //This test compares - //1. correct logID - string logId = "logId"; + // This test compares + // 1. correct logID + var logId = "logId"; string invalidLogId = null; - //2. if the total log calls are the same for global and local - int globalLogCount = 0; - int localLogCount = 0; + // 2. if the total log calls are the same for global and local + //var globalLogCount = 0; + var localLogCount = 0; - MqttNetLogger logger = new MqttNetLogger(logId); + var logger = new MqttNetLogger(logId); - //we have a theoretical bug here if a concurrent test is also logging - var globalLog = new EventHandler((s, e) => - { - if (logId != e.TraceMessage.LogId) - { - invalidLogId = e.TraceMessage.LogId; - } - Interlocked.Increment(ref globalLogCount); - }); + // TODO: This is commented out because it is affected by other tests. + //// we have a theoretical bug here if a concurrent test is also logging + //var globalLog = new EventHandler((s, e) => + //{ + // if (e.TraceMessage.LogId != logId) + // { + // invalidLogId = e.TraceMessage.LogId; + // } + + // Interlocked.Increment(ref globalLogCount); + //}); - MqttNetGlobalLogger.LogMessagePublished += globalLog; + //MqttNetGlobalLogger.LogMessagePublished += globalLog; logger.LogMessagePublished += (s, e) => { - if (logId != e.TraceMessage.LogId) + if (e.TraceMessage.LogId != logId) { invalidLogId = e.TraceMessage.LogId; } + Interlocked.Increment(ref localLogCount); }; @@ -54,10 +57,10 @@ namespace MQTTnet.Tests clientOptions.WithClientOptions(o => o.WithTcpServer("this_is_an_invalid_host").WithCommunicationTimeout(TimeSpan.FromSeconds(1))); - //try connect to get some log entries + // try connect to get some log entries await managedClient.StartAsync(clientOptions.Build()); - //wait at least connect timeout or we have some log messages + // wait at least connect timeout or we have some log messages var tcs = new TaskCompletionSource(); managedClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(e => tcs.TrySetResult(null)); await Task.WhenAny(Task.Delay(managedClient.Options.ClientOptions.CommunicationTimeout), tcs.Task); @@ -66,12 +69,11 @@ namespace MQTTnet.Tests { await managedClient.StopAsync(); - MqttNetGlobalLogger.LogMessagePublished -= globalLog; + //MqttNetGlobalLogger.LogMessagePublished -= globalLog; } Assert.IsNull(invalidLogId); - Assert.AreNotEqual(0, globalLogCount); - Assert.AreEqual(globalLogCount, localLogCount); + Assert.AreNotEqual(0, localLogCount); } } } \ No newline at end of file From 0653b897010d7311ecda13d3c6cef711d47f9926 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Thu, 26 Mar 2020 22:33:30 +0100 Subject: [PATCH 3/4] Fix broken unit tests. --- .../MQTTnet/Implementations/MqttTcpChannel.cs | 46 ++++++++----------- .../PlatformAbstractionLayer.cs | 3 +- Source/MQTTnet/Internal/Disposable.cs | 29 ++++-------- .../Server/MqttClientSessionsManager.cs | 30 ++++++++---- Tests/MQTTnet.Core.Tests/Server_Tests.cs | 28 +++++------ 5 files changed, 65 insertions(+), 71 deletions(-) diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 9b2ba56..71050e1 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -1,25 +1,24 @@ #if !WINDOWS_UWP +using MQTTnet.Channel; +using MQTTnet.Client.Options; using System; -using System.Net.Security; -using System.Net.Sockets; -using System.Security.Cryptography.X509Certificates; -using System.Threading.Tasks; using System.IO; using System.Linq; +using System.Net.Security; +using System.Net.Sockets; using System.Runtime.ExceptionServices; +using System.Security.Cryptography.X509Certificates; using System.Threading; -using MQTTnet.Channel; -using MQTTnet.Client.Options; -using MQTTnet.Internal; +using System.Threading.Tasks; namespace MQTTnet.Implementations { - public class MqttTcpChannel : Disposable, IMqttChannel + public sealed class MqttTcpChannel : IDisposable, IMqttChannel { - private readonly IMqttClientOptions _clientOptions; - private readonly MqttClientTcpOptions _options; + readonly IMqttClientOptions _clientOptions; + readonly MqttClientTcpOptions _options; - private Stream _stream; + Stream _stream; public MqttTcpChannel(IMqttClientOptions clientOptions) { @@ -69,7 +68,7 @@ namespace MQTTnet.Implementations // of the actual value. socket.DualMode = _options.DualMode.Value; } - + // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430 using (cancellationToken.Register(() => socket.Dispose())) { @@ -83,7 +82,7 @@ namespace MQTTnet.Implementations var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback); _stream = sslStream; - await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false); + await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false); } else { @@ -95,12 +94,14 @@ namespace MQTTnet.Implementations public Task DisconnectAsync(CancellationToken cancellationToken) { - Cleanup(); + Dispose(); return Task.FromResult(0); } public async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); + try { // Workaround for: https://github.com/dotnet/corefx/issues/24430 @@ -131,6 +132,8 @@ namespace MQTTnet.Implementations public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); + try { // Workaround for: https://github.com/dotnet/corefx/issues/24430 @@ -159,7 +162,7 @@ namespace MQTTnet.Implementations } } - private void Cleanup() + public void Dispose() { // When the stream is disposed it will also close the socket and this will also dispose it. // So there is no need to dispose the socket again. @@ -178,16 +181,7 @@ namespace MQTTnet.Implementations _stream = null; } - protected override void Dispose(bool disposing) - { - if (disposing) - { - Cleanup(); - } - base.Dispose(disposing); - } - - private bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (_options.TlsOptions.CertificateValidationCallback != null) { @@ -218,7 +212,7 @@ namespace MQTTnet.Implementations return _options.TlsOptions.AllowUntrustedCertificates; } - private X509CertificateCollection LoadCertificates() + X509CertificateCollection LoadCertificates() { var certificates = new X509CertificateCollection(); if (_options.TlsOptions.Certificates == null) diff --git a/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs b/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs index ee9057a..80c0890 100644 --- a/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs +++ b/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs @@ -7,6 +7,7 @@ namespace MQTTnet.Implementations { public static class PlatformAbstractionLayer { + // TODO: Consider creating primitives like "MqttNetSocket" which will wrap all required methods and do the platform stuff. public static async Task AcceptAsync(Socket socket) { #if NET452 || NET461 @@ -90,7 +91,7 @@ namespace MQTTnet.Implementations public static Task CompletedTask { - get + get { #if NET452 return Task.FromResult(0); diff --git a/Source/MQTTnet/Internal/Disposable.cs b/Source/MQTTnet/Internal/Disposable.cs index 2ce3423..e9b05ea 100644 --- a/Source/MQTTnet/Internal/Disposable.cs +++ b/Source/MQTTnet/Internal/Disposable.cs @@ -2,32 +2,20 @@ namespace MQTTnet.Internal { - public class Disposable : IDisposable + public abstract class Disposable : IDisposable { - protected bool IsDisposed => _isDisposed; + protected bool IsDisposed { get; private set; } = false; protected void ThrowIfDisposed() { - if (_isDisposed) + if (IsDisposed) { throw new ObjectDisposedException(GetType().Name); } } - - #region IDisposable Support - - private bool _isDisposed = false; // To detect redundant calls - protected virtual void Dispose(bool disposing) { - if (disposing) - { - // TODO: dispose managed state (managed objects). - } - - // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. - // TODO: set large fields to null. } // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. @@ -40,18 +28,17 @@ namespace MQTTnet.Internal // This code added to correctly implement the disposable pattern. public void Dispose() { - if (_isDisposed) + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + + if (IsDisposed) { return; } - _isDisposed = true; + IsDisposed = true; - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); - // TODO: uncomment the following line if the finalizer is overridden above. - // GC.SuppressFinalize(this); + GC.SuppressFinalize(this); } - #endregion } } diff --git a/Source/MQTTnet/Server/MqttClientSessionsManager.cs b/Source/MQTTnet/Server/MqttClientSessionsManager.cs index 28c163d..6f8ea20 100644 --- a/Source/MQTTnet/Server/MqttClientSessionsManager.cs +++ b/Source/MQTTnet/Server/MqttClientSessionsManager.cs @@ -1,15 +1,16 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using MQTTnet.Adapter; +using MQTTnet.Adapter; using MQTTnet.Diagnostics; +using MQTTnet.Exceptions; using MQTTnet.Formatter; using MQTTnet.Internal; using MQTTnet.Packets; using MQTTnet.Protocol; using MQTTnet.Server.Status; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace MQTTnet.Server { @@ -236,12 +237,23 @@ namespace MQTTnet.Server string clientId = null; var clientWasConnected = true; + MqttConnectPacket connectPacket = null; + try { - var firstPacket = await channelAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken).ConfigureAwait(false); - if (!(firstPacket is MqttConnectPacket connectPacket)) + try + { + var firstPacket = await channelAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken).ConfigureAwait(false); + connectPacket = firstPacket as MqttConnectPacket; + if (connectPacket == null) + { + _logger.Warning(null, "The first packet from client '{0}' was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.Endpoint); + return; + } + } + catch (MqttCommunicationTimedOutException) { - _logger.Warning(null, "The first packet from client '{0}' was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.Endpoint); + _logger.Warning(null, "Client '{0}' connected but did not sent a CONNECT packet.", channelAdapter.Endpoint); return; } diff --git a/Tests/MQTTnet.Core.Tests/Server_Tests.cs b/Tests/MQTTnet.Core.Tests/Server_Tests.cs index 3ebdaa6..6923c69 100644 --- a/Tests/MQTTnet.Core.Tests/Server_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/Server_Tests.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MQTTnet.Adapter; using MQTTnet.Client; using MQTTnet.Client.Connecting; @@ -17,6 +10,13 @@ using MQTTnet.Implementations; using MQTTnet.Protocol; using MQTTnet.Server; using MQTTnet.Tests.Mockups; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; namespace MQTTnet.Tests { @@ -54,7 +54,7 @@ namespace MQTTnet.Tests MqttQualityOfServiceLevel.AtMostOnce, "A/B/C", MqttQualityOfServiceLevel.AtMostOnce, - 1, + 1, TestContext); } @@ -1050,6 +1050,7 @@ namespace MQTTnet.Tests Assert.AreEqual("c", flow); // dc + // Connect client with same client ID. Should disconnect existing client. var c2 = await testEnvironment.ConnectClientAsync(clientOptions); c2.UseApplicationMessageReceivedHandler(_ => @@ -1058,8 +1059,8 @@ namespace MQTTnet.Tests { events.Add("r"); } - }); + c2.SubscribeAsync("topic").Wait(); await Task.Delay(500); @@ -1075,12 +1076,11 @@ namespace MQTTnet.Tests flow = string.Join(string.Empty, events); Assert.AreEqual("cdcr", flow); - // nothing Assert.AreEqual(false, c1.IsConnected); await c1.DisconnectAsync(); - Assert.AreEqual (false, c1.IsConnected); + Assert.AreEqual(false, c1.IsConnected); await Task.Delay(500); @@ -1141,7 +1141,7 @@ namespace MQTTnet.Tests await testEnvironment.ConnectClientAsync(); } } - + [TestMethod] public async Task Close_Idle_Connection() { @@ -1182,7 +1182,7 @@ namespace MQTTnet.Tests // forever. This is security related. var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); await PlatformAbstractionLayer.ConnectAsync(client, "localhost", testEnvironment.ServerPort); - + var buffer = Encoding.UTF8.GetBytes("Garbage"); client.Send(buffer, buffer.Length, SocketFlags.None); From 0da2ab9de68bffeaff55e90fd5d7bd7c855dbd31 Mon Sep 17 00:00:00 2001 From: SeppPenner Date: Mon, 30 Mar 2020 19:46:18 +0200 Subject: [PATCH 4/4] Adjusted copyright information in the nuget package specifications. --- Build/MQTTnet.AspNetCore.nuspec | 2 +- Build/MQTTnet.Extensions.ManagedClient.nuspec | 2 +- Build/MQTTnet.Extensions.Rpc.nuspec | 2 +- Build/MQTTnet.Extensions.WebSocket4Net.nuspec | 2 +- Build/MQTTnet.NETStandard.nuspec | 2 +- Build/MQTTnet.nuspec | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Build/MQTTnet.AspNetCore.nuspec b/Build/MQTTnet.AspNetCore.nuspec index a46cd81..d38efb1 100644 --- a/Build/MQTTnet.AspNetCore.nuspec +++ b/Build/MQTTnet.AspNetCore.nuspec @@ -11,7 +11,7 @@ false This is a support library to integrate MQTTnet into AspNetCore. For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/). - Copyright Christian Kratky 2016-2019 + 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/Build/MQTTnet.Extensions.ManagedClient.nuspec b/Build/MQTTnet.Extensions.ManagedClient.nuspec index edec769..8ae373f 100644 --- a/Build/MQTTnet.Extensions.ManagedClient.nuspec +++ b/Build/MQTTnet.Extensions.ManagedClient.nuspec @@ -11,7 +11,7 @@ false This is an extension library which provides a managed MQTT client with additional features using MQTTnet. For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/). - Copyright Christian Kratky 2016-2019 + 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/Build/MQTTnet.Extensions.Rpc.nuspec b/Build/MQTTnet.Extensions.Rpc.nuspec index ce81cb6..4089ae4 100644 --- a/Build/MQTTnet.Extensions.Rpc.nuspec +++ b/Build/MQTTnet.Extensions.Rpc.nuspec @@ -11,7 +11,7 @@ false This is an extension library which allows executing synchronous device calls including a response using MQTTnet. For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/). - Copyright Christian Kratky 2016-2019 + 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/Build/MQTTnet.Extensions.WebSocket4Net.nuspec b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec index 054933e..0baacdd 100644 --- a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec +++ b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec @@ -11,7 +11,7 @@ false This is an extension library which allows using _WebSocket4Net_ as transport for MQTTnet clients. For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/). - Copyright Christian Kratky 2016-2019 + 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/Build/MQTTnet.NETStandard.nuspec b/Build/MQTTnet.NETStandard.nuspec index c505dd1..ef1b3fa 100644 --- a/Build/MQTTnet.NETStandard.nuspec +++ b/Build/MQTTnet.NETStandard.nuspec @@ -11,7 +11,7 @@ false This package contains the .NET Standard version of MQTTnet only. For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/). - Copyright Christian Kratky 2016-2019 + 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/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index a6e7faf..7e78b6c 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -23,7 +23,7 @@ * [MQTTnet.Server] Added interceptor for unsubscriptions. * [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1 - Copyright Christian Kratky 2016-2019 + 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