From c778cd7a0f8844fe71ebe3388231131b9e3ff2fa Mon Sep 17 00:00:00 2001 From: Jay424 Date: Wed, 28 Oct 2020 17:14:09 +0100 Subject: [PATCH 1/8] Fixed evaluation of IgnoreCertificateRevocationErrors to correctly set SslClientAuthenticationOptions.CertificateRevocationCheckMode The if was just flipped. --- Source/MQTTnet/Implementations/MqttTcpChannel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 5d96740d..8a349ecc 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -87,7 +87,7 @@ namespace MQTTnet.Implementations ApplicationProtocols = _options.TlsOptions.ApplicationProtocols, ClientCertificates = LoadCertificates(), EnabledSslProtocols = _options.TlsOptions.SslProtocol, - CertificateRevocationCheckMode = _options.TlsOptions.IgnoreCertificateRevocationErrors ? X509RevocationMode.Online : X509RevocationMode.NoCheck, + CertificateRevocationCheckMode = _options.TlsOptions.IgnoreCertificateRevocationErrors ? X509RevocationMode.NoCheck : X509RevocationMode.Online, TargetHost = _options.Server }; From 3ea281ff849c0f79461a678aa2f7fe210f95664d Mon Sep 17 00:00:00 2001 From: Jay424 Date: Wed, 28 Oct 2020 17:58:48 +0100 Subject: [PATCH 2/8] Updated release notes --- Build/MQTTnet.nuspec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 16028584..2bf6cb71 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -14,7 +14,8 @@ * [Client] Fixed wrong value for "ClientWasConnected" in "MqttClientDisconnectedEventArgs" #976 (thanks to @dbeinder). * [Client] Added direct support for Amazon AWS connections (requires .NET Core 3.1) (thanks to @henning-krause). -* [Client] handle disconnect package and propagate disconnect reason code (thanks to @JanEggers) +* [Client] handle disconnect package and propagate disconnect reason code (thanks to @JanEggers) +* [Client] Fixed an issue when checking for revoked SSL certificates for target platform NETCOREAPP3_1. * [ManagedClient] Exposed the internal MQTT client. * [Server] Added client message queue interceptor for QoS level (thanks to @msallin). * [Server] improved behavior when multiple connections fight over a session (thanks to @JanEggers) From 7274f4390c253fe6692cb3657c33f91bb8b02fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20=C5=81obacz?= Date: Fri, 30 Oct 2020 12:45:57 +0100 Subject: [PATCH 3/8] added support for Tls1.3 protocol --- .../WebSocket4NetMqttClientAdapterFactory.cs | 4 ++++ Source/MQTTnet.Server/Mqtt/MqttServerService.cs | 6 ++++++ .../MqttClientOptionsBuilderTlsParameters.cs | 4 ++++ .../Client/Options/MqttClientTlsOptions.cs | 4 ++++ .../Implementations/MqttTcpChannel.Uwp.cs | 16 ++++++++++++++++ 5 files changed, 34 insertions(+) diff --git a/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs b/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs index ed29be81..924c13a6 100644 --- a/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs +++ b/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs @@ -52,7 +52,11 @@ namespace MQTTnet.TestApp.NetCore if (channelOptions.TlsOptions.UseTls) { uri = "wss://" + channelOptions.Uri; +#if NETCOREAPP3_0 || NET5_0 + sslProtocols = SslProtocols.Tls13; +#else sslProtocols = SslProtocols.Tls12; +#endif } var subProtocol = channelOptions.SubProtocols.FirstOrDefault() ?? string.Empty; diff --git a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs index 8e5c0435..ac11aa44 100644 --- a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs +++ b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs @@ -212,9 +212,15 @@ namespace MQTTnet.Server.Mqtt // Configure encrypted connections if (_settings.EncryptedTcpEndPoint.Enabled) { +#if NETCOREAPP3_0 || NET5_0 + options + .WithEncryptedEndpoint() + .WithEncryptionSslProtocol(SslProtocols.Tls13); +#else options .WithEncryptedEndpoint() .WithEncryptionSslProtocol(SslProtocols.Tls12); +#endif if (!string.IsNullOrEmpty(_settings.EncryptedTcpEndPoint?.Certificate?.Path)) { diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs index 6f214eb3..8f6abcc8 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs @@ -19,7 +19,11 @@ namespace MQTTnet.Client.Options public Func CertificateValidationHandler { get; set; } +#if NETCOREAPP3_0 || NET5_0 + public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; +#else public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; +#endif #if WINDOWS_UWP public IEnumerable> Certificates { get; set; } diff --git a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs index 106aeb14..da926abd 100644 --- a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs @@ -26,7 +26,11 @@ namespace MQTTnet.Client.Options public List ApplicationProtocols { get; set; } #endif +#if NETCOREAPP3_0 || NET5_0 + public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; +#else public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; +#endif [Obsolete("This property will be removed soon. Use CertificateValidationHandler instead.")] public Func CertificateValidationCallback { get; set; } diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs index ce224057..20b798df 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs @@ -39,7 +39,11 @@ namespace MQTTnet.Implementations CreateStreams(); +#if NETCOREAPP3_0 || NET5_0 + IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls13; +#else IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12; +#endif ClientCertificate = clientCertificate; Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; @@ -75,11 +79,23 @@ namespace MQTTnet.Implementations _socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult); } +#if NETCOREAPP3_0 || NET5_0 + var socketProtectionLevel = SocketProtectionLevel.Tls13; + if (_options.TlsOptions.SslProtocol == SslProtocols.Tls12) + { + socketProtectionLevel = SocketProtectionLevel.Tls12; + } + else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11) + { + socketProtectionLevel = SocketProtectionLevel.Tls11; + } +#else var socketProtectionLevel = SocketProtectionLevel.Tls12; if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11) { socketProtectionLevel = SocketProtectionLevel.Tls11; } +#endif else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls) { socketProtectionLevel = SocketProtectionLevel.Tls10; From 3208045baab5ecb37f0a9aee5a96eb606a00f10b Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Fri, 30 Oct 2020 20:42:52 +0100 Subject: [PATCH 4/8] Extend application message builder. --- Source/MQTTnet/MqttApplicationMessageBuilder.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/MQTTnet/MqttApplicationMessageBuilder.cs b/Source/MQTTnet/MqttApplicationMessageBuilder.cs index c265e4d1..bc2d9b86 100644 --- a/Source/MQTTnet/MqttApplicationMessageBuilder.cs +++ b/Source/MQTTnet/MqttApplicationMessageBuilder.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -103,6 +104,16 @@ namespace MQTTnet return this; } + public MqttApplicationMessageBuilder WithQualityOfServiceLevel(int qualityOfServiceLevel) + { + if (qualityOfServiceLevel < 0 || qualityOfServiceLevel > 2) + { + throw new ArgumentOutOfRangeException(nameof(qualityOfServiceLevel)); + } + + return WithQualityOfServiceLevel((MqttQualityOfServiceLevel)qualityOfServiceLevel); + } + public MqttApplicationMessageBuilder WithRetainFlag(bool value = true) { _retain = value; From 4e9df988179c5fef90c8bf035e3f44efd487f7f3 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Fri, 30 Oct 2020 20:43:02 +0100 Subject: [PATCH 5/8] Improve test environment. --- Tests/MQTTnet.Core.Tests/Mockups/TestEnvironment.cs | 9 ++++++--- Tests/MQTTnet.Core.Tests/Server_Tests.cs | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Tests/MQTTnet.Core.Tests/Mockups/TestEnvironment.cs b/Tests/MQTTnet.Core.Tests/Mockups/TestEnvironment.cs index 3fb399e9..5800bf43 100644 --- a/Tests/MQTTnet.Core.Tests/Mockups/TestEnvironment.cs +++ b/Tests/MQTTnet.Core.Tests/Mockups/TestEnvironment.cs @@ -66,10 +66,13 @@ namespace MQTTnet.Tests.Mockups public IMqttClient CreateClient() { - var client = _mqttFactory.CreateMqttClient(ClientLogger); - _clients.Add(client); + lock (_clients) + { + var client = _mqttFactory.CreateMqttClient(ClientLogger); + _clients.Add(client); - return new TestClientWrapper(client, TestContext); + return new TestClientWrapper(client, TestContext); + } } public Task StartServerAsync() diff --git a/Tests/MQTTnet.Core.Tests/Server_Tests.cs b/Tests/MQTTnet.Core.Tests/Server_Tests.cs index 16db377e..71c819d1 100644 --- a/Tests/MQTTnet.Core.Tests/Server_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/Server_Tests.cs @@ -646,11 +646,11 @@ namespace MQTTnet.Tests { // Clear retained message. await client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + i2) - .WithPayload(new byte[0]).WithRetainFlag().Build()); + .WithPayload(new byte[0]).WithRetainFlag().WithQualityOfServiceLevel(1).Build()); // Set retained message. await client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + i2) - .WithPayload("value").WithRetainFlag().Build()); + .WithPayload("value").WithRetainFlag().WithQualityOfServiceLevel(1).Build()); await client.DisconnectAsync(); } From 558d281a332fd026c8f5db2da2f35fb50e25414e Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sat, 31 Oct 2020 11:23:14 +0100 Subject: [PATCH 6/8] Refactor TLS 1.3 support. --- Build/MQTTnet.nuspec | 2 +- .../WebSocket4NetMqttChannel.cs | 16 ++++++++-------- Source/MQTTnet.Server/Mqtt/MqttServerService.cs | 2 +- .../MqttClientOptionsBuilderTlsParameters.cs | 2 +- .../Client/Options/MqttClientTlsOptions.cs | 2 +- .../Implementations/MqttTcpChannel.Uwp.cs | 8 ++------ 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index c15d5321..42042a0e 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -12,7 +12,7 @@ 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. -* [Server] .. +* [Core] Added support for TLS 1.3 (requires .NET Core 3.1+) (thanks to @Dvergatal). 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 Blazor diff --git a/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs b/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs index 47d96821..120e6c36 100644 --- a/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs +++ b/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs @@ -16,14 +16,14 @@ using WebSocket4Net; namespace MQTTnet.Extensions.WebSocket4Net { - public class WebSocket4NetMqttChannel : IMqttChannel + public sealed class WebSocket4NetMqttChannel : IMqttChannel { - private readonly BlockingCollection _receiveBuffer = new BlockingCollection(); + readonly BlockingCollection _receiveBuffer = new BlockingCollection(); - private readonly IMqttClientOptions _clientOptions; - private readonly MqttClientWebSocketOptions _webSocketOptions; + readonly IMqttClientOptions _clientOptions; + readonly MqttClientWebSocketOptions _webSocketOptions; - private WebSocket _webSocket; + WebSocket _webSocket; public WebSocket4NetMqttChannel(IMqttClientOptions clientOptions, MqttClientWebSocketOptions webSocketOptions) { @@ -166,12 +166,12 @@ namespace MQTTnet.Extensions.WebSocket4Net _webSocket = null; } - private void OnError(object sender, ErrorEventArgs e) + static void OnError(object sender, ErrorEventArgs e) { System.Diagnostics.Debug.Write(e.Exception.ToString()); } - private void OnDataReceived(object sender, DataReceivedEventArgs e) + void OnDataReceived(object sender, DataReceivedEventArgs e) { foreach (var @byte in e.Data) { @@ -179,7 +179,7 @@ namespace MQTTnet.Extensions.WebSocket4Net } } - private async Task ConnectInternalAsync(CancellationToken cancellationToken) + async Task ConnectInternalAsync(CancellationToken cancellationToken) { _webSocket.Error += OnError; _webSocket.DataReceived += OnDataReceived; diff --git a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs index ac11aa44..bdb57624 100644 --- a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs +++ b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs @@ -212,7 +212,7 @@ namespace MQTTnet.Server.Mqtt // Configure encrypted connections if (_settings.EncryptedTcpEndPoint.Enabled) { -#if NETCOREAPP3_0 || NET5_0 +#if NETCOREAPP3_1 || NET5_0 options .WithEncryptedEndpoint() .WithEncryptionSslProtocol(SslProtocols.Tls13); diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs index 8f6abcc8..f73ab3b7 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs @@ -19,7 +19,7 @@ namespace MQTTnet.Client.Options public Func CertificateValidationHandler { get; set; } -#if NETCOREAPP3_0 || NET5_0 +#if NETCOREAPP3_1 || NET5_0 public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; #else public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; diff --git a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs index da926abd..b5e2c261 100644 --- a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs @@ -26,7 +26,7 @@ namespace MQTTnet.Client.Options public List ApplicationProtocols { get; set; } #endif -#if NETCOREAPP3_0 || NET5_0 +#if NETCOREAPP3_1 || NET5_0 public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; #else public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs index 20b798df..7d5706dd 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs @@ -39,11 +39,7 @@ namespace MQTTnet.Implementations CreateStreams(); -#if NETCOREAPP3_0 || NET5_0 - IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls13; -#else IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12; -#endif ClientCertificate = clientCertificate; Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; @@ -79,7 +75,7 @@ namespace MQTTnet.Implementations _socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult); } -#if NETCOREAPP3_0 || NET5_0 +#if NETCOREAPP3_1 || NET5_0 var socketProtectionLevel = SocketProtectionLevel.Tls13; if (_options.TlsOptions.SslProtocol == SslProtocols.Tls12) { @@ -89,7 +85,7 @@ namespace MQTTnet.Implementations { socketProtectionLevel = SocketProtectionLevel.Tls11; } -#else +#else var socketProtectionLevel = SocketProtectionLevel.Tls12; if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11) { From 838d50c1d393a28236c91990fc23df621ffd395d Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sat, 31 Oct 2020 11:27:46 +0100 Subject: [PATCH 7/8] Remove file which is not part of the solution. --- .../WebSocket4NetMqttClientAdapterFactory.cs | 138 ------------------ 1 file changed, 138 deletions(-) delete mode 100644 Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs diff --git a/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs b/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs deleted file mode 100644 index 924c13a6..00000000 --- a/Source/MQTTnet.Extensions.Wrappers.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs +++ /dev/null @@ -1,138 +0,0 @@ -using MQTTnet.Client; -using System; -using System.Collections.Concurrent; -using System.Linq; -using System.Security.Authentication; -using System.Threading; -using System.Threading.Tasks; -using MQTTnet.Adapter; -using MQTTnet.Channel; -using MQTTnet.Diagnostics; -using MQTTnet.Serializer; -using WebSocket4Net; - -namespace MQTTnet.TestApp.NetCore -{ - public class WebSocket4NetMqttClientAdapterFactory : IMqttClientAdapterFactory - { - public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger) - { - if (options == null) throw new ArgumentNullException(nameof(options)); - if (logger == null) throw new ArgumentNullException(nameof(logger)); - - if (!(options.ChannelOptions is MqttClientWebSocketOptions)) - { - throw new NotSupportedException("Only WebSocket connections are supported."); - } - - return new MqttChannelAdapter(new WebSocket4NetMqttChannel(options), new MqttPacketSerializer(), logger); - } - - private class WebSocket4NetMqttChannel : IMqttChannel - { - private readonly BlockingCollection _receiveBuffer = new BlockingCollection(); - - private readonly IMqttClientOptions _clientOptions; - private WebSocket4Net.WebSocket _webSocket; - - public WebSocket4NetMqttChannel(IMqttClientOptions clientOptions) - { - _clientOptions = clientOptions ?? throw new ArgumentNullException(nameof(clientOptions)); - } - - public string Endpoint { get; } = ""; - - public Task ConnectAsync(CancellationToken cancellationToken) - { - var channelOptions = (MqttClientWebSocketOptions)_clientOptions.ChannelOptions; - - var uri = "ws://" + channelOptions.Uri; - var sslProtocols = SslProtocols.None; - - if (channelOptions.TlsOptions.UseTls) - { - uri = "wss://" + channelOptions.Uri; -#if NETCOREAPP3_0 || NET5_0 - sslProtocols = SslProtocols.Tls13; -#else - sslProtocols = SslProtocols.Tls12; -#endif - } - - var subProtocol = channelOptions.SubProtocols.FirstOrDefault() ?? string.Empty; - - _webSocket = new WebSocket4Net.WebSocket(uri, subProtocol, sslProtocols: sslProtocols); - _webSocket.DataReceived += OnDataReceived; - _webSocket.Open(); - SpinWait.SpinUntil(() => _webSocket.State == WebSocketState.Open, _clientOptions.CommunicationTimeout); - - return Task.FromResult(0); - } - - public Task DisconnectAsync() - { - if (_webSocket != null) - { - _webSocket.DataReceived -= OnDataReceived; - _webSocket.Close(); - SpinWait.SpinUntil(() => _webSocket.State == WebSocketState.Closed, _clientOptions.CommunicationTimeout); - } - - _webSocket = null; - - return Task.FromResult(0); - } - - public Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - var readBytes = 0; - while (count > 0 && !cancellationToken.IsCancellationRequested) - { - byte @byte; - if (readBytes == 0) - { - // Block until at lease one byte was received. - @byte = _receiveBuffer.Take(cancellationToken); - } - else - { - if (!_receiveBuffer.TryTake(out @byte)) - { - return Task.FromResult(readBytes); - } - } - - buffer[offset] = @byte; - offset++; - count--; - readBytes++; - } - - return Task.FromResult(readBytes); - } - - public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - _webSocket.Send(buffer, offset, count); - return Task.FromResult(0); - } - - public void Dispose() - { - if (_webSocket != null) - { - _webSocket.DataReceived -= OnDataReceived; - _webSocket.Dispose(); - } - } - - private void OnDataReceived(object sender, WebSocket4Net.DataReceivedEventArgs e) - { - foreach (var @byte in e.Data) - { - _receiveBuffer.Add(@byte); - } - } - } - } -} From 34ae54d5422819486bf9f50a76dc8f4390b8fba0 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sat, 31 Oct 2020 11:33:44 +0100 Subject: [PATCH 8/8] Improve Unit Tests. --- .../MqttClientDisconnectedEventArgs.cs | 13 +++++++++---- Tests/MQTTnet.Core.Tests/Server_Tests.cs | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Source/MQTTnet/Client/Disconnecting/MqttClientDisconnectedEventArgs.cs b/Source/MQTTnet/Client/Disconnecting/MqttClientDisconnectedEventArgs.cs index 24b45345..5e2317cf 100644 --- a/Source/MQTTnet/Client/Disconnecting/MqttClientDisconnectedEventArgs.cs +++ b/Source/MQTTnet/Client/Disconnecting/MqttClientDisconnectedEventArgs.cs @@ -3,14 +3,16 @@ using MQTTnet.Client.Connecting; namespace MQTTnet.Client.Disconnecting { - public class MqttClientDisconnectedEventArgs : EventArgs + public sealed class MqttClientDisconnectedEventArgs : EventArgs { - public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult, MqttClientDisconnectReason reasonCode) + public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult, MqttClientDisconnectReason reason) { ClientWasConnected = clientWasConnected; Exception = exception; AuthenticateResult = authenticateResult; - ReasonCode = reasonCode; + Reason = reason; + + ReasonCode = reason; } public bool ClientWasConnected { get; } @@ -19,6 +21,9 @@ namespace MQTTnet.Client.Disconnecting public MqttClientAuthenticateResult AuthenticateResult { get; } - public MqttClientDisconnectReason ReasonCode { get; set; } = MqttClientDisconnectReason.NormalDisconnection; + public MqttClientDisconnectReason Reason { get; set; } + + [Obsolete("Please use 'Reason' instead. This property will be removed in the future!")] + public MqttClientDisconnectReason ReasonCode { get; set; } } } diff --git a/Tests/MQTTnet.Core.Tests/Server_Tests.cs b/Tests/MQTTnet.Core.Tests/Server_Tests.cs index 71c819d1..4c00af6a 100644 --- a/Tests/MQTTnet.Core.Tests/Server_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/Server_Tests.cs @@ -471,11 +471,19 @@ namespace MQTTnet.Tests var client1 = await testEnvironment.ConnectClientAsync(options); await Task.Delay(500); + MqttClientDisconnectReason disconnectReason = MqttClientDisconnectReason.NormalDisconnection; + client1.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(c => + { + disconnectReason = c.Reason; + }); + var client2 = await testEnvironment.ConnectClientAsync(options); await Task.Delay(500); Assert.IsFalse(client1.IsConnected); Assert.IsTrue(client2.IsConnected); + + Assert.AreEqual(MqttClientDisconnectReason.SessionTakenOver, disconnectReason); } }