From bdb74642c2ed9d16ecdf2f7f9300b68f5206155a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Sat, 30 Nov 2024 20:46:36 +0800 Subject: [PATCH 1/7] MqttClientFactory: Fix CreateLowLevelMqttClient not using method parameters (#2110) * Fix CreateLowLevelMqttClient not using method parameters. * Remove UseClientAdapterFactory() --- Source/MQTTnet/MqttClientFactory.cs | 38 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/Source/MQTTnet/MqttClientFactory.cs b/Source/MQTTnet/MqttClientFactory.cs index 2e5504df0..8994ee988 100644 --- a/Source/MQTTnet/MqttClientFactory.cs +++ b/Source/MQTTnet/MqttClientFactory.cs @@ -11,24 +11,31 @@ namespace MQTTnet; -public sealed class MqttClientFactory +public class MqttClientFactory { - IMqttClientAdapterFactory _clientAdapterFactory; + readonly IMqttNetLogger _logger; + readonly IMqttClientAdapterFactory _clientAdapterFactory; - public MqttClientFactory() : this(new MqttNetNullLogger()) + public IMqttNetLogger DefaultLogger => _logger; + + public IDictionary Properties { get; } = new Dictionary(); + + public MqttClientFactory() + : this(new MqttNetNullLogger()) { } public MqttClientFactory(IMqttNetLogger logger) + : this(logger, new MqttClientAdapterFactory()) { - DefaultLogger = logger ?? throw new ArgumentNullException(nameof(logger)); - - _clientAdapterFactory = new MqttClientAdapterFactory(); } - public IMqttNetLogger DefaultLogger { get; } + public MqttClientFactory(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactory) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _clientAdapterFactory = clientAdapterFactory ?? throw new ArgumentNullException(nameof(clientAdapterFactory)); + } - public IDictionary Properties { get; } = new Dictionary(); public MqttApplicationMessageBuilder CreateApplicationMessageBuilder() { @@ -47,7 +54,7 @@ public MqttClientOptionsBuilder CreateClientOptionsBuilder() public ILowLevelMqttClient CreateLowLevelMqttClient() { - return CreateLowLevelMqttClient(DefaultLogger); + return new LowLevelMqttClient(_clientAdapterFactory, _logger); } public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger) @@ -61,7 +68,7 @@ public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttClientAdapterFactory cl { ArgumentNullException.ThrowIfNull(clientAdapterFactory); - return new LowLevelMqttClient(_clientAdapterFactory, DefaultLogger); + return new LowLevelMqttClient(clientAdapterFactory, _logger); } public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactory) @@ -69,12 +76,12 @@ public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger, IMqtt ArgumentNullException.ThrowIfNull(logger); ArgumentNullException.ThrowIfNull(clientAdapterFactory); - return new LowLevelMqttClient(_clientAdapterFactory, logger); + return new LowLevelMqttClient(clientAdapterFactory, logger); } public IMqttClient CreateMqttClient() { - return CreateMqttClient(DefaultLogger); + return new MqttClient(_clientAdapterFactory, _logger); } public IMqttClient CreateMqttClient(IMqttNetLogger logger) @@ -88,7 +95,7 @@ public IMqttClient CreateMqttClient(IMqttClientAdapterFactory clientAdapterFacto { ArgumentNullException.ThrowIfNull(clientAdapterFactory); - return new MqttClient(clientAdapterFactory, DefaultLogger); + return new MqttClient(clientAdapterFactory, _logger); } public IMqttClient CreateMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactory) @@ -114,9 +121,4 @@ public MqttClientUnsubscribeOptionsBuilder CreateUnsubscribeOptionsBuilder() return new MqttClientUnsubscribeOptionsBuilder(); } - public MqttClientFactory UseClientAdapterFactory(IMqttClientAdapterFactory clientAdapterFactory) - { - _clientAdapterFactory = clientAdapterFactory ?? throw new ArgumentNullException(nameof(clientAdapterFactory)); - return this; - } } \ No newline at end of file From 7d4027958c16b3a06936146ec4b6032046c8d1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Sun, 1 Dec 2024 21:06:19 +0800 Subject: [PATCH 2/7] Set the default value of SslProtocol to SslProtocols.None. (#2106) * Set the default value of SslProtocol to SslProtocols.None. * Add summary of SslProtocol. --- .../Options/MqttServerTlsTcpEndpointOptions.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/MQTTnet.Server/Options/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet.Server/Options/MqttServerTlsTcpEndpointOptions.cs index 135e012d6..fb8a1b02c 100644 --- a/Source/MQTTnet.Server/Options/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet.Server/Options/MqttServerTlsTcpEndpointOptions.cs @@ -22,7 +22,11 @@ public MqttServerTlsTcpEndpointOptions() public bool CheckCertificateRevocation { get; set; } - public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; + /// + /// The default value is SslProtocols.None, which allows the operating system to choose the best protocol to use, and to block protocols that are not secure. + /// + /// SslProtocols + public SslProtocols SslProtocol { get; set; } = SslProtocols.None; public System.Net.Security.CipherSuitesPolicy CipherSuitesPolicy { get; set; } } From 6ef6b57064212ad7e99eeb5bc982e605c91336e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Sun, 1 Dec 2024 21:10:58 +0800 Subject: [PATCH 3/7] Improve the compatibility of MqttClientOptionsBuilder.WithConnectionUri() (#2107) * Improve the compatibility of MqttClientOptionsBuilder.WithConnectionUri() method. * Force UseTls to true for secure schemes. * Add support for UnixDomainSocket. --- .../Options/MqttClientOptionsBuilder.cs | 39 ++++++++++++++----- .../MqttClientWebSocketOptionsBuilder.cs | 6 +++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs index 0afb64de0..4d0f486ec 100644 --- a/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs +++ b/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs @@ -1,15 +1,15 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using MQTTnet.Formatter; +using MQTTnet.Packets; +using MQTTnet.Protocol; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; -using MQTTnet.Formatter; -using MQTTnet.Packets; -using MQTTnet.Protocol; namespace MQTTnet; @@ -138,20 +138,39 @@ public MqttClientOptionsBuilder WithConnectionUri(Uri uri) { case "tcp": case "mqtt": - WithTcpServer(uri.Host, port); + WithTcpServer(uri.Host, port) + .WithAddressFamily(AddressFamily.Unspecified) + .WithProtocolType(ProtocolType.Tcp) + .WithTlsOptions(o => o.UseTls(false)); break; case "mqtts": WithTcpServer(uri.Host, port) - .WithTlsOptions( - o => - { - }); + .WithAddressFamily(AddressFamily.Unspecified) + .WithProtocolType(ProtocolType.Tcp) + .WithTlsOptions(o => o.UseTls(true)); break; case "ws": + WithWebSocketServer(o => o.WithUri(uri.ToString())) + .WithAddressFamily(AddressFamily.Unspecified) + .WithProtocolType(ProtocolType.Tcp) + .WithTlsOptions(o => o.UseTls(false)); + break; + case "wss": - WithWebSocketServer(o => o.WithUri(uri.ToString())); + WithWebSocketServer(o => o.WithUri(uri.ToString())) + .WithAddressFamily(AddressFamily.Unspecified) + .WithProtocolType(ProtocolType.Tcp) + .WithTlsOptions(o => o.UseTls(true)); + break; + + // unix:///path/to/socket + case "unix": + WithEndPoint(new UnixDomainSocketEndPoint(uri.AbsolutePath)) + .WithAddressFamily(AddressFamily.Unix) + .WithProtocolType(ProtocolType.Unspecified) + .WithTlsOptions(o => o.UseTls(false)); break; default: diff --git a/Source/MQTTnet/Options/MqttClientWebSocketOptionsBuilder.cs b/Source/MQTTnet/Options/MqttClientWebSocketOptionsBuilder.cs index 59ec023cc..6d334e809 100644 --- a/Source/MQTTnet/Options/MqttClientWebSocketOptionsBuilder.cs +++ b/Source/MQTTnet/Options/MqttClientWebSocketOptionsBuilder.cs @@ -66,6 +66,12 @@ public MqttClientWebSocketOptionsBuilder WithSubProtocols(ICollection su public MqttClientWebSocketOptionsBuilder WithUri(string uri) { + var webSocketUri = new Uri(uri, UriKind.Absolute); + if (webSocketUri.Scheme != Uri.UriSchemeWs && webSocketUri.Scheme != Uri.UriSchemeWss) + { + throw new ArgumentException("The scheme of the WebSocket Uri must be ws or wss."); + } + _webSocketOptions.Uri = uri; return this; } From 6bf2b4eacaadb0510a3da01289d2ae62ea409ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Mon, 2 Dec 2024 17:24:03 +0800 Subject: [PATCH 4/7] Cannot set any properties of tcpOptions when with WebSocketServer. (#2118) --- Source/MQTTnet/Options/MqttClientOptionsBuilder.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs index 4d0f486ec..a4dedff97 100644 --- a/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs +++ b/Source/MQTTnet/Options/MqttClientOptionsBuilder.cs @@ -153,15 +153,11 @@ public MqttClientOptionsBuilder WithConnectionUri(Uri uri) case "ws": WithWebSocketServer(o => o.WithUri(uri.ToString())) - .WithAddressFamily(AddressFamily.Unspecified) - .WithProtocolType(ProtocolType.Tcp) .WithTlsOptions(o => o.UseTls(false)); break; case "wss": WithWebSocketServer(o => o.WithUri(uri.ToString())) - .WithAddressFamily(AddressFamily.Unspecified) - .WithProtocolType(ProtocolType.Tcp) .WithTlsOptions(o => o.UseTls(true)); break; From 4aa4a12e476709ff2c03f76fab46b146f2979773 Mon Sep 17 00:00:00 2001 From: christian <6939810+chkr1011@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:40:05 +0100 Subject: [PATCH 5/7] Update release notes --- Source/ReleaseNotes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/ReleaseNotes.md b/Source/ReleaseNotes.md index 629ad7e8c..47fc8a553 100644 --- a/Source/ReleaseNotes.md +++ b/Source/ReleaseNotes.md @@ -8,4 +8,5 @@ * Namespace changes **(BREAKING CHANGE)** * Removal of Managed Client **(BREAKING CHANGE)** * Client: MQTT 5.0.0 is now the default version when connecting with a server **(BREAKING CHANGE)** -* Server: Set default for "MaxPendingMessagesPerClient" to 1000 **(BREAKING CHANGE)** \ No newline at end of file +* Server: Set default for "MaxPendingMessagesPerClient" to 1000 **(BREAKING CHANGE)** +* Server: Set SSL version to "None" which will let the OS choose the version **(BREAKING CHANGE)** \ No newline at end of file From 8089c6bdbcfd1a63821352e3f34717df62486790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E4=B9=9D?= <366193849@qq.com> Date: Mon, 2 Dec 2024 18:52:24 +0800 Subject: [PATCH 6/7] Added EndPoint RemoteEndPoint {get;} property to channel (#2111) * Added EndPoint RemoteEndPoint{get;} property * Reformat code * Reformat code --------- Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com> --- .../MqttConnectionContext.cs | 6 ++--- .../MqttWebSocketServerAdapter.cs | 6 +++-- .../MQTTnet.Benchmarks/SerializerBenchmark.cs | 3 ++- .../Events/ClientConnectedEventArgs.cs | 10 ++++--- .../Events/ClientDisconnectedEventArgs.cs | 10 ++++--- .../Events/InterceptingPacketEventArgs.cs | 10 ++++--- .../Events/ValidatingConnectionEventArgs.cs | 6 ++++- .../Internal/Adapter/MqttTcpServerListener.cs | 4 +-- .../Internal/MqttClientSessionsManager.cs | 27 +++++++++++-------- .../Internal/MqttConnectedClient.cs | 17 ++++++------ .../MQTTnet.Server/Status/MqttClientStatus.cs | 6 ++++- Source/MQTTnet.TestApp/ServerTest.cs | 4 ++- .../Mockups/MemoryMqttChannel.cs | 4 ++- Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs | 5 ++-- Source/MQTTnet.Tests/Server/Events_Tests.cs | 4 +-- Source/MQTTnet/Adapter/IMqttChannelAdapter.cs | 4 ++- Source/MQTTnet/Adapter/MqttChannelAdapter.cs | 3 ++- Source/MQTTnet/Channel/IMqttChannel.cs | 3 ++- .../MQTTnet/Implementations/MqttTcpChannel.cs | 8 +++--- .../Implementations/MqttWebSocketChannel.cs | 6 ++--- 20 files changed, 91 insertions(+), 55 deletions(-) diff --git a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs index c16e5f483..61184c4d5 100644 --- a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs +++ b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs @@ -61,21 +61,21 @@ public X509Certificate2 ClientCertificate } } - public string Endpoint + public EndPoint RemoteEndPoint { get { // mqtt over tcp if (_connection.RemoteEndPoint != null) { - return _connection.RemoteEndPoint.ToString(); + return _connection.RemoteEndPoint; } // mqtt over websocket var httpFeature = _connection.Features.Get(); if (httpFeature?.RemoteIpAddress != null) { - return new IPEndPoint(httpFeature.RemoteIpAddress, httpFeature.RemotePort).ToString(); + return new IPEndPoint(httpFeature.RemoteIpAddress, httpFeature.RemotePort); } return null; diff --git a/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs b/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs index 272ead6bf..18a382a12 100644 --- a/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs +++ b/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Net; using System.Net.WebSockets; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -28,7 +29,8 @@ public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext h { ArgumentNullException.ThrowIfNull(webSocket); - var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}"; + var remoteAddress = httpContext.Connection.RemoteIpAddress; + var remoteEndPoint = remoteAddress == null ? null : new IPEndPoint(remoteAddress, httpContext.Connection.RemotePort); var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false); try @@ -39,7 +41,7 @@ public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext h if (clientHandler != null) { var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535)); - var channel = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection, clientCertificate); + var channel = new MqttWebSocketChannel(webSocket, remoteEndPoint, isSecureConnection, clientCertificate); using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger)) { diff --git a/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs b/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs index 0ddea15f1..48117232c 100644 --- a/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs +++ b/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs @@ -15,6 +15,7 @@ using BenchmarkDotNet.Jobs; using MQTTnet.Diagnostics.Logger; using System.Buffers; +using System.Net; namespace MQTTnet.Benchmarks { @@ -76,7 +77,7 @@ public BenchmarkMqttChannel(ArraySegment buffer) _position = _buffer.Offset; } - public string Endpoint { get; } = string.Empty; + public EndPoint RemoteEndPoint { get; set; } public bool IsSecureConnection { get; } = false; diff --git a/Source/MQTTnet.Server/Events/ClientConnectedEventArgs.cs b/Source/MQTTnet.Server/Events/ClientConnectedEventArgs.cs index 216f96efb..27701db6f 100644 --- a/Source/MQTTnet.Server/Events/ClientConnectedEventArgs.cs +++ b/Source/MQTTnet.Server/Events/ClientConnectedEventArgs.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Net; using MQTTnet.Formatter; using MQTTnet.Packets; @@ -14,11 +15,11 @@ public sealed class ClientConnectedEventArgs : EventArgs { readonly MqttConnectPacket _connectPacket; - public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, string endpoint, IDictionary sessionItems) + public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, EndPoint remoteEndPoint, IDictionary sessionItems) { _connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket)); ProtocolVersion = protocolVersion; - Endpoint = endpoint; + RemoteEndPoint = remoteEndPoint; SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems)); } @@ -35,7 +36,10 @@ public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVer /// /// Gets the endpoint of the connected client. /// - public string Endpoint { get; } + public EndPoint RemoteEndPoint { get; } + + [Obsolete("Use RemoteEndPoint instead.")] + public string Endpoint => RemoteEndPoint?.ToString(); /// /// Gets the protocol version which is used by the connected client. diff --git a/Source/MQTTnet.Server/Events/ClientDisconnectedEventArgs.cs b/Source/MQTTnet.Server/Events/ClientDisconnectedEventArgs.cs index bbc5d148d..b552e4e96 100644 --- a/Source/MQTTnet.Server/Events/ClientDisconnectedEventArgs.cs +++ b/Source/MQTTnet.Server/Events/ClientDisconnectedEventArgs.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Net; using MQTTnet.Packets; using MQTTnet.Protocol; @@ -18,12 +19,12 @@ public ClientDisconnectedEventArgs( string clientId, MqttDisconnectPacket disconnectPacket, MqttClientDisconnectType disconnectType, - string endpoint, + EndPoint remoteEndPoint, IDictionary sessionItems) { ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId)); DisconnectType = disconnectType; - Endpoint = endpoint; + RemoteEndPoint = remoteEndPoint; SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems)); // The DISCONNECT packet can be null in case of a non clean disconnect or session takeover. @@ -38,7 +39,10 @@ public ClientDisconnectedEventArgs( public MqttClientDisconnectType DisconnectType { get; } - public string Endpoint { get; } + public EndPoint RemoteEndPoint { get; } + + [Obsolete("Use RemoteEndPoint instead.")] + public string Endpoint => RemoteEndPoint?.ToString(); /// /// Gets the reason code sent by the client. diff --git a/Source/MQTTnet.Server/Events/InterceptingPacketEventArgs.cs b/Source/MQTTnet.Server/Events/InterceptingPacketEventArgs.cs index df62b54a4..0b1eef2e8 100644 --- a/Source/MQTTnet.Server/Events/InterceptingPacketEventArgs.cs +++ b/Source/MQTTnet.Server/Events/InterceptingPacketEventArgs.cs @@ -4,6 +4,7 @@ using System; using System.Collections; +using System.Net; using System.Threading; using MQTTnet.Packets; @@ -11,11 +12,11 @@ namespace MQTTnet.Server { public sealed class InterceptingPacketEventArgs : EventArgs { - public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, string endpoint, MqttPacket packet, IDictionary sessionItems) + public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, EndPoint remoteEndPoint, MqttPacket packet, IDictionary sessionItems) { CancellationToken = cancellationToken; ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId)); - Endpoint = endpoint; + RemoteEndPoint = remoteEndPoint; Packet = packet ?? throw new ArgumentNullException(nameof(packet)); SessionItems = sessionItems; } @@ -34,7 +35,10 @@ public InterceptingPacketEventArgs(CancellationToken cancellationToken, string c /// /// Gets the endpoint of the sending or receiving client. /// - public string Endpoint { get; } + public EndPoint RemoteEndPoint { get; } + + [Obsolete("Use RemoteEndPoint instead.")] + public string Endpoint => RemoteEndPoint?.ToString(); /// /// Gets or sets the MQTT packet which was received or will be sent. diff --git a/Source/MQTTnet.Server/Events/ValidatingConnectionEventArgs.cs b/Source/MQTTnet.Server/Events/ValidatingConnectionEventArgs.cs index cf44bdf52..325973c7e 100644 --- a/Source/MQTTnet.Server/Events/ValidatingConnectionEventArgs.cs +++ b/Source/MQTTnet.Server/Events/ValidatingConnectionEventArgs.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Net; using System.Security.Cryptography.X509Certificates; using System.Text; using MQTTnet.Adapter; @@ -70,7 +71,10 @@ public ValidatingConnectionEventArgs(MqttConnectPacket connectPacket, IMqttChann /// public string ClientId => _connectPacket.ClientId; - public string Endpoint => ChannelAdapter.Endpoint; + public EndPoint RemoteEndPoint => ChannelAdapter.RemoteEndPoint; + + [Obsolete("Use RemoteEndPoint instead.")] + public string Endpoint => RemoteEndPoint?.ToString(); public bool IsSecureConnection => ChannelAdapter.IsSecureConnection; diff --git a/Source/MQTTnet.Server/Internal/Adapter/MqttTcpServerListener.cs b/Source/MQTTnet.Server/Internal/Adapter/MqttTcpServerListener.cs index fc76b0575..7a0453ce8 100644 --- a/Source/MQTTnet.Server/Internal/Adapter/MqttTcpServerListener.cs +++ b/Source/MQTTnet.Server/Internal/Adapter/MqttTcpServerListener.cs @@ -167,11 +167,11 @@ async Task AcceptClientConnectionsAsync(CancellationToken cancellationToken) async Task TryHandleClientConnectionAsync(CrossPlatformSocket clientSocket) { Stream stream = null; - string remoteEndPoint = null; + EndPoint remoteEndPoint = null; try { - remoteEndPoint = clientSocket.RemoteEndPoint.ToString(); + remoteEndPoint = clientSocket.RemoteEndPoint; _logger.Verbose("TCP client '{0}' accepted (Local endpoint={1})", remoteEndPoint, _localEndPoint); diff --git a/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs b/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs index 6c0cf68ec..67728a8d3 100644 --- a/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs +++ b/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs @@ -19,22 +19,18 @@ namespace MQTTnet.Server.Internal; public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification, IDisposable { readonly Dictionary _clients = new(4096); - readonly AsyncLock _createConnectionSyncRoot = new(); - readonly MqttServerEventContainer _eventContainer; readonly MqttNetSourceLogger _logger; readonly MqttServerOptions _options; - readonly MqttRetainedMessagesManager _retainedMessagesManager; readonly IMqttNetLogger _rootLogger; - readonly ReaderWriterLockSlim _sessionsManagementLock = new(); // The _sessions dictionary contains all session, the _subscriberSessions hash set contains subscriber sessions only. // See the MqttSubscription object for a detailed explanation. readonly MqttSessionsStorage _sessionsStorage = new(); - readonly HashSet _subscriberSessions = new(); + readonly HashSet _subscriberSessions = []; public MqttClientSessionsManager(MqttServerOptions options, MqttRetainedMessagesManager retainedMessagesManager, MqttServerEventContainer eventContainer, IMqttNetLogger logger) { @@ -365,7 +361,11 @@ public async Task HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter if (_eventContainer.ClientConnectedEvent.HasHandlers) { - var eventArgs = new ClientConnectedEventArgs(connectPacket, channelAdapter.PacketFormatterAdapter.ProtocolVersion, channelAdapter.Endpoint, connectedClient.Session.Items); + var eventArgs = new ClientConnectedEventArgs( + connectPacket, + channelAdapter.PacketFormatterAdapter.ProtocolVersion, + channelAdapter.RemoteEndPoint, + connectedClient.Session.Items); await _eventContainer.ClientConnectedEvent.TryInvokeAsync(eventArgs, _logger).ConfigureAwait(false); } @@ -403,7 +403,7 @@ public async Task HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter } } - var endpoint = connectedClient.Endpoint; + var endpoint = connectedClient.RemoteEndPoint; if (connectedClient.Id != null && !connectedClient.IsTakenOver && _eventContainer.ClientDisconnectedEvent.HasHandlers) { @@ -591,7 +591,12 @@ async Task CreateClientConnection( if (_eventContainer.ClientDisconnectedEvent.HasHandlers) { - var eventArgs = new ClientDisconnectedEventArgs(oldConnectedClient.Id, null, MqttClientDisconnectType.Takeover, oldConnectedClient.Endpoint, oldConnectedClient.Session.Items); + var eventArgs = new ClientDisconnectedEventArgs( + oldConnectedClient.Id, + null, + MqttClientDisconnectType.Takeover, + oldConnectedClient.RemoteEndPoint, + oldConnectedClient.Session.Items); await _eventContainer.ClientDisconnectedEvent.TryInvokeAsync(eventArgs, _logger).ConfigureAwait(false); } @@ -655,14 +660,14 @@ async Task ReceiveConnectPacket(IMqttChannelAdapter channelAd } catch (OperationCanceledException) { - _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint); + _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.RemoteEndPoint); } catch (MqttCommunicationTimedOutException) { - _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint); + _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.RemoteEndPoint); } - _logger.Warning("Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.Endpoint); + _logger.Warning("Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.RemoteEndPoint); return null; } diff --git a/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs b/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs index 2217def09..84f26570d 100644 --- a/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs +++ b/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Net; using MQTTnet.Adapter; using MQTTnet.Diagnostics.Logger; using MQTTnet.Exceptions; @@ -45,7 +46,7 @@ public MqttConnectedClient( ConnectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket)); ChannelAdapter = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter)); - Endpoint = channelAdapter.Endpoint; + RemoteEndPoint = channelAdapter.RemoteEndPoint; Session = session ?? throw new ArgumentNullException(nameof(session)); ArgumentNullException.ThrowIfNull(logger); @@ -59,14 +60,14 @@ public MqttConnectedClient( public MqttDisconnectPacket DisconnectPacket { get; private set; } - public string Endpoint { get; } - public string Id => ConnectPacket.ClientId; public bool IsRunning { get; private set; } public bool IsTakenOver { get; set; } + public EndPoint RemoteEndPoint { get; } + public MqttSession Session { get; } public MqttClientStatistics Statistics { get; } = new(); @@ -338,7 +339,7 @@ async Task InterceptPacketAsync(MqttPacket packet, CancellationToken return packet; } - var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, Endpoint, packet, Session.Items); + var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, RemoteEndPoint, packet, Session.Items); await _eventContainer.InterceptingOutboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false); if (!interceptingPacketEventArgs.ProcessPacket || packet == null) @@ -384,7 +385,7 @@ async Task ReceivePackagesLoop(CancellationToken cancellationToken) if (_eventContainer.InterceptingInboundPacketEvent.HasHandlers) { - var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, Endpoint, currentPacket, Session.Items); + var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, RemoteEndPoint, currentPacket, Session.Items); await _eventContainer.InterceptingInboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false); currentPacket = interceptingPacketEventArgs.Packet; processPacket = interceptingPacketEventArgs.ProcessPacket; @@ -560,10 +561,8 @@ async Task TrySendDisconnectPacket(MqttServerClientDisconnectOptions options) var disconnectPacket = MqttDisconnectPacketFactory.Create(options); - using (var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout)) - { - await SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false); - } + using var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout); + await SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false); } catch (Exception exception) { diff --git a/Source/MQTTnet.Server/Status/MqttClientStatus.cs b/Source/MQTTnet.Server/Status/MqttClientStatus.cs index 447dde223..f39e7ab68 100644 --- a/Source/MQTTnet.Server/Status/MqttClientStatus.cs +++ b/Source/MQTTnet.Server/Status/MqttClientStatus.cs @@ -4,6 +4,7 @@ using MQTTnet.Formatter; using MQTTnet.Server.Internal; +using System.Net; namespace MQTTnet.Server; @@ -22,7 +23,10 @@ public MqttClientStatus(MqttConnectedClient client) public DateTime ConnectedTimestamp => _client.Statistics.ConnectedTimestamp; - public string Endpoint => _client.Endpoint; + public EndPoint RemoteEndPoint => _client.RemoteEndPoint; + + [Obsolete("Use RemoteEndPoint instead.")] + public string Endpoint => RemoteEndPoint?.ToString(); /// /// Gets or sets the client identifier. diff --git a/Source/MQTTnet.TestApp/ServerTest.cs b/Source/MQTTnet.TestApp/ServerTest.cs index be5273a13..241abcca3 100644 --- a/Source/MQTTnet.TestApp/ServerTest.cs +++ b/Source/MQTTnet.TestApp/ServerTest.cs @@ -43,7 +43,9 @@ public static async Task RunAsync() { try { - var options = new MqttServerOptions(); + var options = new MqttServerOptionsBuilder() + .WithDefaultEndpoint() + .Build(); // Extend the timestamp for all messages from clients. // Protect several topics from being subscribed from every client. diff --git a/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs b/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs index db2fb462a..20c76602b 100644 --- a/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs +++ b/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs @@ -2,10 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.AspNetCore.Http; using MQTTnet.Channel; using MQTTnet.Internal; using System.Buffers; using System.IO; +using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -26,7 +28,7 @@ public MemoryMqttChannel(byte[] buffer) _stream = new MemoryStream(buffer); } - public string Endpoint { get; } = ""; + public EndPoint RemoteEndPoint { get; set; } public bool IsSecureConnection { get; } = false; diff --git a/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs b/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs index 3813e23b2..caad82f6c 100644 --- a/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs +++ b/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs @@ -40,10 +40,11 @@ public async Task Dispose_Channel_While_Used() }, ct.Token); + var remoteEndPoint = new DnsEndPoint("localhost", 50001); using var clientSocket = new CrossPlatformSocket(AddressFamily.InterNetwork, ProtocolType.Tcp); - await clientSocket.ConnectAsync(new DnsEndPoint("localhost", 50001), CancellationToken.None); + await clientSocket.ConnectAsync(remoteEndPoint, CancellationToken.None); - var tcpChannel = new MqttTcpChannel(clientSocket.GetStream(), "test", null); + var tcpChannel = new MqttTcpChannel(clientSocket.GetStream(), remoteEndPoint, null); await Task.Delay(100, ct.Token); diff --git a/Source/MQTTnet.Tests/Server/Events_Tests.cs b/Source/MQTTnet.Tests/Server/Events_Tests.cs index 0720fa235..415a2a2d2 100644 --- a/Source/MQTTnet.Tests/Server/Events_Tests.cs +++ b/Source/MQTTnet.Tests/Server/Events_Tests.cs @@ -36,7 +36,7 @@ public async Task Fire_Client_Connected_Event() Assert.IsNotNull(eventArgs); Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Connected_Event))); - Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1")); + Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1")); Assert.AreEqual(MqttProtocolVersion.V311, eventArgs.ProtocolVersion); Assert.AreEqual("TheUser", eventArgs.UserName); } @@ -64,7 +64,7 @@ public async Task Fire_Client_Disconnected_Event() Assert.IsNotNull(eventArgs); Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Disconnected_Event))); - Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1")); + Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1")); Assert.AreEqual(MqttClientDisconnectType.Clean, eventArgs.DisconnectType); } } diff --git a/Source/MQTTnet/Adapter/IMqttChannelAdapter.cs b/Source/MQTTnet/Adapter/IMqttChannelAdapter.cs index 7fe35dfca..9337354a0 100644 --- a/Source/MQTTnet/Adapter/IMqttChannelAdapter.cs +++ b/Source/MQTTnet/Adapter/IMqttChannelAdapter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -18,7 +19,8 @@ public interface IMqttChannelAdapter : IDisposable long BytesSent { get; } X509Certificate2 ClientCertificate { get; } - string Endpoint { get; } + + EndPoint RemoteEndPoint { get; } bool IsSecureConnection { get; } diff --git a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs index 390fe9420..28d72bcf2 100644 --- a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs +++ b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs @@ -5,6 +5,7 @@ using System; using System.Buffers; using System.IO; +using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; @@ -51,7 +52,7 @@ public MqttChannelAdapter(IMqttChannel channel, MqttPacketFormatterAdapter packe public X509Certificate2 ClientCertificate => _channel.ClientCertificate; - public string Endpoint => _channel.Endpoint; + public EndPoint RemoteEndPoint => _channel.RemoteEndPoint; public bool IsSecureConnection => _channel.IsSecureConnection; diff --git a/Source/MQTTnet/Channel/IMqttChannel.cs b/Source/MQTTnet/Channel/IMqttChannel.cs index 55cd48ba0..02af43e46 100644 --- a/Source/MQTTnet/Channel/IMqttChannel.cs +++ b/Source/MQTTnet/Channel/IMqttChannel.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; +using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -13,7 +14,7 @@ namespace MQTTnet.Channel; public interface IMqttChannel : IDisposable { X509Certificate2 ClientCertificate { get; } - string Endpoint { get; } + EndPoint RemoteEndPoint { get; } bool IsSecureConnection { get; } diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 050b30013..5ef20c1a6 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -37,11 +37,11 @@ public MqttTcpChannel(MqttClientOptions clientOptions) : this() IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true; } - public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCertificate) : this() + public MqttTcpChannel(Stream stream, EndPoint remoteEndPoint, X509Certificate2 clientCertificate) : this() { _stream = stream ?? throw new ArgumentNullException(nameof(stream)); - Endpoint = endpoint; + RemoteEndPoint = remoteEndPoint; IsSecureConnection = stream is SslStream; ClientCertificate = clientCertificate; @@ -49,7 +49,7 @@ public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCer public X509Certificate2 ClientCertificate { get; } - public string Endpoint { get; private set; } + public EndPoint RemoteEndPoint { get; private set; } public bool IsSecureConnection { get; } @@ -175,7 +175,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken) _stream = networkStream; } - Endpoint = socket.RemoteEndPoint?.ToString(); + RemoteEndPoint = socket.RemoteEndPoint; } catch (Exception) { diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs index 0227dce46..8c7e59114 100644 --- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs +++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs @@ -26,18 +26,18 @@ public MqttWebSocketChannel(MqttClientWebSocketOptions options) _options = options ?? throw new ArgumentNullException(nameof(options)); } - public MqttWebSocketChannel(WebSocket webSocket, string endpoint, bool isSecureConnection, X509Certificate2 clientCertificate) + public MqttWebSocketChannel(WebSocket webSocket, EndPoint remoteEndPoint, bool isSecureConnection, X509Certificate2 clientCertificate) { _webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket)); - Endpoint = endpoint; + RemoteEndPoint = remoteEndPoint; IsSecureConnection = isSecureConnection; ClientCertificate = clientCertificate; } public X509Certificate2 ClientCertificate { get; } - public string Endpoint { get; } + public EndPoint RemoteEndPoint { get; } public bool IsSecureConnection { get; private set; } From 8566fd53952bdaed3e24a8bd6a792a4c7253385a Mon Sep 17 00:00:00 2001 From: Christian <6939810+chkr1011@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:40:06 +0100 Subject: [PATCH 7/7] Replace all _DataTestMethod_ (#2119) * Replace all DataTestMethod with TestMethod. * Update test nugets --- Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj | 2 +- Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs | 2 +- Source/MQTTnet.Tests/MQTTnet.Tests.csproj | 6 +++--- Source/MQTTnet.Tests/Server/Session_Tests.cs | 2 +- Source/MQTTnet.Tests/Server/Subscribe_Tests.cs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj b/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj index d5e1f11f9..d50ca5cd9 100644 --- a/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj +++ b/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj @@ -18,7 +18,7 @@ - + diff --git a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs index 19c63d24e..b8b1ba9e2 100644 --- a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs +++ b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs @@ -27,7 +27,7 @@ namespace MQTTnet.Tests.Clients.MqttClient [TestClass] public sealed class MqttClient_Tests : BaseTestClass { - [DataTestMethod] + [TestMethod] [DataRow(MqttQualityOfServiceLevel.ExactlyOnce)] [DataRow(MqttQualityOfServiceLevel.AtMostOnce)] [DataRow(MqttQualityOfServiceLevel.AtLeastOnce)] diff --git a/Source/MQTTnet.Tests/MQTTnet.Tests.csproj b/Source/MQTTnet.Tests/MQTTnet.Tests.csproj index b29190740..c89d8057b 100644 --- a/Source/MQTTnet.Tests/MQTTnet.Tests.csproj +++ b/Source/MQTTnet.Tests/MQTTnet.Tests.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/Source/MQTTnet.Tests/Server/Session_Tests.cs b/Source/MQTTnet.Tests/Server/Session_Tests.cs index bf03c9a18..91345da56 100644 --- a/Source/MQTTnet.Tests/Server/Session_Tests.cs +++ b/Source/MQTTnet.Tests/Server/Session_Tests.cs @@ -182,7 +182,7 @@ void OnReceive() } } - [DataTestMethod] + [TestMethod] [DataRow(MqttQualityOfServiceLevel.ExactlyOnce)] [DataRow(MqttQualityOfServiceLevel.AtLeastOnce)] public async Task Retry_If_Not_PubAck(MqttQualityOfServiceLevel qos) diff --git a/Source/MQTTnet.Tests/Server/Subscribe_Tests.cs b/Source/MQTTnet.Tests/Server/Subscribe_Tests.cs index a764ce87e..9dd48c317 100644 --- a/Source/MQTTnet.Tests/Server/Subscribe_Tests.cs +++ b/Source/MQTTnet.Tests/Server/Subscribe_Tests.cs @@ -20,7 +20,7 @@ namespace MQTTnet.Tests.Server [TestClass] public sealed class Subscribe_Tests : BaseTestClass { - [DataTestMethod] + [TestMethod] [DataRow("A", "A", true)] [DataRow("A", "B", false)] [DataRow("A", "#", true)]