From ee6ec14bf8f69c9db7ff1ffe5c57f730c7d82ef1 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sat, 25 Nov 2017 20:12:50 +0100 Subject: [PATCH] Add interface for server options. Add context class for connection validator (hide internal packets). --- Build/MQTTnet.AspNetCore.nuspec | 6 ++-- .../MqttWebSocketServerAdapter.cs | 2 +- .../ServiceCollectionExtensions.cs | 2 +- .../Adapter/IMqttServerAdapter.cs | 2 +- .../Implementations/MqttServerAdapter.Uwp.cs | 2 +- .../Implementations/MqttServerAdapter.cs | 2 +- .../MQTTnet.NetStandard/Server/IMqttServer.cs | 2 +- .../Server/IMqttServerOptions.cs | 16 ++++++++++ .../Server/MqttClientPendingMessagesQueue.cs | 4 +-- .../Server/MqttClientSession.cs | 4 +-- .../Server/MqttClientSessionsManager.cs | 19 ++++++++---- .../Server/MqttClientSubscriptionsManager.cs | 4 +-- .../Server/MqttRetainedMessagesManager.cs | 4 +-- .../MQTTnet.NetStandard/Server/MqttServer.cs | 4 +-- .../Server/MqttServerOptions.cs | 6 ++-- .../Server/MqttServerOptionsBuilder.cs | 6 ++-- .../Server/MqttServerOptionsExtensions.cs | 4 +-- .../TestMqttServerAdapter.cs | 2 +- Tests/MQTTnet.TestApp.NetCore/ServerTest.cs | 4 +-- .../MainPage.xaml.cs | 31 ++++++++++++------- 20 files changed, 75 insertions(+), 51 deletions(-) create mode 100644 Frameworks/MQTTnet.NetStandard/Server/IMqttServerOptions.cs diff --git a/Build/MQTTnet.AspNetCore.nuspec b/Build/MQTTnet.AspNetCore.nuspec index 3a862ba..1510b2d 100644 --- a/Build/MQTTnet.AspNetCore.nuspec +++ b/Build/MQTTnet.AspNetCore.nuspec @@ -2,7 +2,7 @@ MQTTnet.AspNetCore - 2.5.3 + 2.6.0 Christian Kratky Christian Kratky https://github.com/chkr1011/MQTTnet/blob/master/LICENSE @@ -10,13 +10,13 @@ https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png false This is a support library to integrate MQTTnet into AspNetCore. - * Updated to MQTTnet 2.5.3. + * Updated to MQTTnet 2.6.0. Copyright Christian Kratky 2016-2017 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/Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs b/Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs index 5af8b64..a2ca627 100644 --- a/Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs +++ b/Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs @@ -12,7 +12,7 @@ namespace MQTTnet.AspNetCore { public event EventHandler ClientAccepted; - public Task StartAsync(MqttServerOptions options) + public Task StartAsync(IMqttServerOptions options) { return Task.CompletedTask; } diff --git a/Frameworks/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs b/Frameworks/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs index a6af6eb..d4bdf39 100644 --- a/Frameworks/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs +++ b/Frameworks/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs @@ -9,7 +9,7 @@ namespace MQTTnet.AspNetCore { public static class ServiceCollectionExtensions { - public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, MqttServerOptions options) + public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, IMqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); diff --git a/Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs b/Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs index d4ea941..bd583f5 100644 --- a/Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs +++ b/Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs @@ -8,7 +8,7 @@ namespace MQTTnet.Adapter { event EventHandler ClientAccepted; - Task StartAsync(MqttServerOptions options); + Task StartAsync(IMqttServerOptions options); Task StopAsync(); } } diff --git a/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.Uwp.cs b/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.Uwp.cs index 3966edc..96fbae4 100644 --- a/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.Uwp.cs +++ b/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.Uwp.cs @@ -21,7 +21,7 @@ namespace MQTTnet.Implementations public event EventHandler ClientAccepted; - public async Task StartAsync(MqttServerOptions options) + public async Task StartAsync(IMqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); diff --git a/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.cs b/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.cs index dadca44..d4ab095 100644 --- a/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.cs +++ b/Frameworks/MQTTnet.NetStandard/Implementations/MqttServerAdapter.cs @@ -30,7 +30,7 @@ namespace MQTTnet.Implementations public event EventHandler ClientAccepted; - public Task StartAsync(MqttServerOptions options) + public Task StartAsync(IMqttServerOptions options) { if (_cancellationTokenSource != null) throw new InvalidOperationException("Server is already started."); diff --git a/Frameworks/MQTTnet.NetStandard/Server/IMqttServer.cs b/Frameworks/MQTTnet.NetStandard/Server/IMqttServer.cs index 3d0ccda..926ab9d 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/IMqttServer.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/IMqttServer.cs @@ -12,7 +12,7 @@ namespace MQTTnet.Server Task> GetConnectedClientsAsync(); - Task StartAsync(MqttServerOptions options); + Task StartAsync(IMqttServerOptions options); Task StopAsync(); } } \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetStandard/Server/IMqttServerOptions.cs b/Frameworks/MQTTnet.NetStandard/Server/IMqttServerOptions.cs new file mode 100644 index 0000000..92c1bfb --- /dev/null +++ b/Frameworks/MQTTnet.NetStandard/Server/IMqttServerOptions.cs @@ -0,0 +1,16 @@ +using System; + +namespace MQTTnet.Server +{ + public interface IMqttServerOptions + { + Action ApplicationMessageInterceptor { get; } + int ConnectionBacklog { get; } + Action ConnectionValidator { get; } + TimeSpan DefaultCommunicationTimeout { get; } + MqttServerDefaultEndpointOptions DefaultEndpointOptions { get; } + IMqttServerStorage Storage { get; } + Action SubscriptionInterceptor { get; } + MqttServerTlsEndpointOptions TlsEndpointOptions { get; } + } +} \ No newline at end of file diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientPendingMessagesQueue.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientPendingMessagesQueue.cs index 9e1a2cd..a64dfbf 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientPendingMessagesQueue.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientPendingMessagesQueue.cs @@ -13,11 +13,11 @@ namespace MQTTnet.Server public sealed class MqttClientPendingMessagesQueue { private readonly BlockingCollection _pendingPublishPackets = new BlockingCollection(); - private readonly MqttServerOptions _options; + private readonly IMqttServerOptions _options; private readonly MqttClientSession _session; private readonly IMqttNetLogger _logger; - public MqttClientPendingMessagesQueue(MqttServerOptions options, MqttClientSession session, IMqttNetLogger logger) + public MqttClientPendingMessagesQueue(IMqttServerOptions options, MqttClientSession session, IMqttNetLogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _session = session ?? throw new ArgumentNullException(nameof(session)); diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs index cc88964..f871ad3 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs @@ -19,7 +19,7 @@ namespace MQTTnet.Server private readonly MqttClientSubscriptionsManager _subscriptionsManager; private readonly MqttClientSessionsManager _sessionsManager; private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue; - private readonly MqttServerOptions _options; + private readonly IMqttServerOptions _options; private readonly IMqttNetLogger _logger; private IMqttChannelAdapter _adapter; @@ -28,7 +28,7 @@ namespace MQTTnet.Server public MqttClientSession( string clientId, - MqttServerOptions options, + IMqttServerOptions options, MqttClientSessionsManager sessionsManager, IMqttNetLogger logger) { diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs index 61e19f7..7d647d9 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs @@ -18,11 +18,11 @@ namespace MQTTnet.Server private readonly Dictionary _sessions = new Dictionary(); private readonly SemaphoreSlim _sessionsSemaphore = new SemaphoreSlim(1, 1); - private readonly MqttServerOptions _options; + private readonly IMqttServerOptions _options; private readonly MqttRetainedMessagesManager _retainedMessagesManager; private readonly IMqttNetLogger _logger; - public MqttClientSessionsManager(MqttServerOptions options, MqttRetainedMessagesManager retainedMessagesManager, IMqttNetLogger logger) + public MqttClientSessionsManager(IMqttServerOptions options, MqttRetainedMessagesManager retainedMessagesManager, IMqttNetLogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _options = options ?? throw new ArgumentNullException(nameof(options)); @@ -174,12 +174,19 @@ namespace MQTTnet.Server private MqttConnectReturnCode ValidateConnection(MqttConnectPacket connectPacket) { - if (_options.ConnectionValidator != null) + if (_options.ConnectionValidator == null) { - return _options.ConnectionValidator(connectPacket); + return MqttConnectReturnCode.ConnectionAccepted; } - - return MqttConnectReturnCode.ConnectionAccepted; + + var context = new MqttConnectionValidatorContext( + connectPacket.ClientId, + connectPacket.Username, + connectPacket.Password, + connectPacket.WillMessage); + + _options.ConnectionValidator(context); + return context.ReturnCode; } private async Task GetOrCreateClientSessionAsync(MqttConnectPacket connectPacket) diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSubscriptionsManager.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSubscriptionsManager.cs index 8615630..1276b06 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSubscriptionsManager.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSubscriptionsManager.cs @@ -8,9 +8,9 @@ namespace MQTTnet.Server public sealed class MqttClientSubscriptionsManager { private readonly Dictionary _subscriptions = new Dictionary(); - private readonly MqttServerOptions _options; + private readonly IMqttServerOptions _options; - public MqttClientSubscriptionsManager(MqttServerOptions options) + public MqttClientSubscriptionsManager(IMqttServerOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); } diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttRetainedMessagesManager.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttRetainedMessagesManager.cs index c837769..0b8d669 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttRetainedMessagesManager.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttRetainedMessagesManager.cs @@ -13,9 +13,9 @@ namespace MQTTnet.Server private readonly Dictionary _retainedMessages = new Dictionary(); private readonly SemaphoreSlim _gate = new SemaphoreSlim(1, 1); private readonly IMqttNetLogger _logger; - private readonly MqttServerOptions _options; + private readonly IMqttServerOptions _options; - public MqttRetainedMessagesManager(MqttServerOptions options, IMqttNetLogger logger) + public MqttRetainedMessagesManager(IMqttServerOptions options, IMqttNetLogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _options = options ?? throw new ArgumentNullException(nameof(options)); diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttServer.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttServer.cs index 25dc2d3..42c6854 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttServer.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttServer.cs @@ -16,7 +16,7 @@ namespace MQTTnet.Server private MqttClientSessionsManager _clientSessionsManager; private MqttRetainedMessagesManager _retainedMessagesManager; private CancellationTokenSource _cancellationTokenSource; - private MqttServerOptions _options; + private IMqttServerOptions _options; public MqttServer(IEnumerable adapters, IMqttNetLogger logger) { @@ -52,7 +52,7 @@ namespace MQTTnet.Server } } - public async Task StartAsync(MqttServerOptions options) + public async Task StartAsync(IMqttServerOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptions.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptions.cs index d04725e..2b0a9a0 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptions.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptions.cs @@ -1,10 +1,8 @@ using System; -using MQTTnet.Packets; -using MQTTnet.Protocol; namespace MQTTnet.Server { - public class MqttServerOptions + public class MqttServerOptions : IMqttServerOptions { public MqttServerDefaultEndpointOptions DefaultEndpointOptions { get; } = new MqttServerDefaultEndpointOptions(); @@ -14,7 +12,7 @@ namespace MQTTnet.Server public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(15); - public Func ConnectionValidator { get; set; } + public Action ConnectionValidator { get; set; } public Action ApplicationMessageInterceptor { get; set; } diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsBuilder.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsBuilder.cs index f6cb0bb..34f36a9 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsBuilder.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsBuilder.cs @@ -1,6 +1,4 @@ using System; -using MQTTnet.Packets; -using MQTTnet.Protocol; namespace MQTTnet.Server { @@ -62,7 +60,7 @@ namespace MQTTnet.Server return this; } - public MqttServerOptionsBuilder WithConnectionValidator(Func value) + public MqttServerOptionsBuilder WithConnectionValidator(Action value) { _options.ConnectionValidator = value; return this; @@ -80,7 +78,7 @@ namespace MQTTnet.Server return this; } - public MqttServerOptions Build() + public IMqttServerOptions Build() { return _options; } diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsExtensions.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsExtensions.cs index 0324624..db93ef1 100644 --- a/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsExtensions.cs +++ b/Frameworks/MQTTnet.NetStandard/Server/MqttServerOptionsExtensions.cs @@ -4,7 +4,7 @@ namespace MQTTnet.Server { public static class MqttServerOptionsExtensions { - public static int GetTlsEndpointPort(this MqttServerOptions options) + public static int GetTlsEndpointPort(this IMqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); @@ -16,7 +16,7 @@ namespace MQTTnet.Server return options.TlsEndpointOptions.Port.Value; } - public static int GetDefaultEndpointPort(this MqttServerOptions options) + public static int GetDefaultEndpointPort(this IMqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); diff --git a/Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs b/Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs index ea53512..a2fec80 100644 --- a/Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs +++ b/Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs @@ -62,7 +62,7 @@ namespace MQTTnet.Core.Tests ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(adapter)); } - public Task StartAsync(MqttServerOptions options) + public Task StartAsync(IMqttServerOptions options) { return Task.FromResult(0); } diff --git a/Tests/MQTTnet.TestApp.NetCore/ServerTest.cs b/Tests/MQTTnet.TestApp.NetCore/ServerTest.cs index 767db08..d4960d0 100644 --- a/Tests/MQTTnet.TestApp.NetCore/ServerTest.cs +++ b/Tests/MQTTnet.TestApp.NetCore/ServerTest.cs @@ -23,11 +23,9 @@ namespace MQTTnet.TestApp.NetCore { if (p.Username != "USER" || p.Password != "PASS") { - return MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + p.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; } } - - return MqttConnectReturnCode.ConnectionAccepted; }, Storage = new RetainedMessageHandler(), diff --git a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs index 5d943be..a750b27 100644 --- a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs +++ b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs @@ -354,20 +354,23 @@ namespace MQTTnet.TestApp.UniversalWindows { if (c.ClientId.Length < 10) { - return MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + return; } if (c.Username != "mySecretUser") { - return MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + return; } if (c.Password != "mySecretPassword") { - return MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + return; } - return MqttConnectReturnCode.ConnectionAccepted; + c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted; }; var factory = new MqttFactory(); @@ -410,14 +413,15 @@ namespace MQTTnet.TestApp.UniversalWindows }; options.DefaultEndpointOptions.Port = 1884; - options.ConnectionValidator = packet => + options.ConnectionValidator = c => { - if (packet.ClientId != "Highlander") + if (c.ClientId != "Highlander") { - return MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + return; } - return MqttConnectReturnCode.ConnectionAccepted; + c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted; }; var mqttServer = new MqttFactory().CreateMqttServer(); @@ -432,20 +436,23 @@ namespace MQTTnet.TestApp.UniversalWindows { if (c.ClientId.Length < 10) { - return MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected; + return; } if (c.Username != "mySecretUser") { - return MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + return; } if (c.Password != "mySecretPassword") { - return MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword; + return; } - return MqttConnectReturnCode.ConnectionAccepted; + c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted; } }; }