Move events to server level instead of options.

This commit is contained in:
Christian
2021-10-27 22:01:45 +02:00
parent 7297336786
commit d411aa4f97
109 changed files with 1148 additions and 2096 deletions
@@ -36,9 +36,9 @@ namespace MQTTnet.AspNetCore.Extensions
return app;
}
public static IApplicationBuilder UseMqttServer(this IApplicationBuilder app, Action<IMqttServer> configure)
public static IApplicationBuilder UseMqttServer(this IApplicationBuilder app, Action<MqttServer> configure)
{
var server = app.ApplicationServices.GetRequiredService<IMqttServer>();
var server = app.ApplicationServices.GetRequiredService<MqttServer>();
configure(server);
@@ -11,7 +11,7 @@ namespace MQTTnet.AspNetCore.Extensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, IMqttServerOptions options)
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, MqttServerOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
@@ -24,7 +24,7 @@ namespace MQTTnet.AspNetCore.Extensions
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, Action<MqttServerOptionsBuilder> configure)
{
services.AddSingleton<IMqttServerOptions>(s =>
services.AddSingleton<MqttServerOptions>(s =>
{
var builder = new MqttServerOptionsBuilder();
configure(builder);
@@ -38,7 +38,7 @@ namespace MQTTnet.AspNetCore.Extensions
public static IServiceCollection AddHostedMqttServerWithServices(this IServiceCollection services, Action<AspNetMqttServerOptionsBuilder> configure)
{
services.AddSingleton<IMqttServerOptions>(s =>
services.AddSingleton<MqttServerOptions>(s =>
{
var builder = new AspNetMqttServerOptionsBuilder(s);
configure(builder);
@@ -50,17 +50,17 @@ namespace MQTTnet.AspNetCore.Extensions
return services;
}
public static IServiceCollection AddHostedMqttServer<TOptions>(this IServiceCollection services)
where TOptions : class, IMqttServerOptions
{
services.AddSingleton<IMqttServerOptions, TOptions>();
// public static IServiceCollection AddHostedMqttServer<TOptions>(this IServiceCollection services)
// where TOptions : MqttServerOptions
// {
// services.AddSingleton<MqttServerOptions, TOptions>();
//
// services.AddHostedMqttServer();
//
// return services;
// }
services.AddHostedMqttServer();
return services;
}
private static IServiceCollection AddHostedMqttServer(this IServiceCollection services)
static IServiceCollection AddHostedMqttServer(this IServiceCollection services)
{
var logger = new MqttNetEventLogger();
@@ -33,7 +33,7 @@ namespace MQTTnet.AspNetCore
}
}
public Task StartAsync(IMqttServerOptions options)
public Task StartAsync(MqttServerOptions options)
{
return Task.CompletedTask;
}
+9 -65
View File
@@ -1,32 +1,26 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using MQTTnet.Adapter;
using MQTTnet.Client.Publishing;
using MQTTnet.Client.Receiving;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Server;
using MQTTnet.Server.Status;
namespace MQTTnet.AspNetCore
{
public sealed class MqttHostedServer : IMqttServer, IHostedService
{
readonly MqttServer _mqttServer;
readonly IMqttServerOptions _options;
public MqttHostedServer(IMqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
public MqttHostedServer(MqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_mqttServer = new MqttServer(adapters, logger);
_mqttServer = new MqttServer(options, adapters, logger);
}
public Task StartAsync(CancellationToken cancellationToken)
{
_ = _mqttServer.StartAsync(_options);
_ = _mqttServer.StartAsync();
return Task.CompletedTask;
}
@@ -34,22 +28,10 @@ namespace MQTTnet.AspNetCore
{
return _mqttServer.StopAsync();
}
public IMqttApplicationMessageReceivedHandler ApplicationMessageReceivedHandler
{
get => _mqttServer.ApplicationMessageReceivedHandler;
set => _mqttServer.ApplicationMessageReceivedHandler = value;
}
public event Func<MqttApplicationMessageReceivedEventArgs, Task> ApplicationMessageReceivedAsync
{
add => _mqttServer.ApplicationMessageReceivedAsync += value;
remove => _mqttServer.ApplicationMessageReceivedAsync -= value;
}
public Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
public Task<MqttClientPublishResult> PublishAsync(string senderClientId, MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
{
return _mqttServer.PublishAsync(applicationMessage, cancellationToken);
return _mqttServer.PublishAsync(senderClientId, applicationMessage, cancellationToken);
}
public void Dispose()
@@ -58,45 +40,7 @@ namespace MQTTnet.AspNetCore
}
public bool IsStarted => _mqttServer.IsStarted;
public IMqttServerStartedHandler StartedHandler
{
get => _mqttServer.StartedHandler;
set => _mqttServer.StartedHandler = value;
}
public IMqttServerStoppedHandler StoppedHandler
{
get => _mqttServer.StoppedHandler;
set => _mqttServer.StoppedHandler = value;
}
public IMqttServerClientConnectedHandler ClientConnectedHandler
{
get => _mqttServer.ClientConnectedHandler;
set => _mqttServer.ClientConnectedHandler = value;
}
public IMqttServerClientDisconnectedHandler ClientDisconnectedHandler
{
get => _mqttServer.ClientDisconnectedHandler;
set => _mqttServer.ClientDisconnectedHandler = value;
}
public IMqttServerClientSubscribedTopicHandler ClientSubscribedTopicHandler
{
get => _mqttServer.ClientSubscribedTopicHandler;
set => _mqttServer.ClientSubscribedTopicHandler = value;
}
public IMqttServerClientUnsubscribedTopicHandler ClientUnsubscribedTopicHandler
{
get => _mqttServer.ClientUnsubscribedTopicHandler;
set => _mqttServer.ClientUnsubscribedTopicHandler = value;
}
public IMqttServerOptions Options => _mqttServer.Options;
public Task<IList<IMqttClientStatus>> GetClientStatusAsync()
{
return _mqttServer.GetClientStatusAsync();
@@ -127,9 +71,9 @@ namespace MQTTnet.AspNetCore
return _mqttServer.UnsubscribeAsync(clientId, topicFilters);
}
public Task StartAsync(IMqttServerOptions options)
public Task StartAsync()
{
return _mqttServer.StartAsync(options);
return _mqttServer.StartAsync();
}
public Task StopAsync()
@@ -21,7 +21,7 @@ namespace MQTTnet.AspNetCore
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public Task StartAsync(IMqttServerOptions options)
public Task StartAsync(MqttServerOptions options)
{
return Task.CompletedTask;
}
@@ -8,7 +8,7 @@ using MQTTnet.Client;
namespace MQTTnet.Extensions.ManagedClient
{
public interface IManagedMqttClient : IApplicationMessageReceiver, IApplicationMessagePublisher, IDisposable
public interface IManagedMqttClient : IMqttApplicationMessageReceiver, IMqttApplicationMessagePublisher, IDisposable
{
/// <summary>
/// Gets the internally used MQTT client.
@@ -77,7 +77,7 @@ namespace MQTTnet.Extensions.ManagedClient
}
public static TReceiver UseApplicationMessageReceivedHandler<TReceiver>(this TReceiver receiver, Func<MqttApplicationMessageReceivedEventArgs, Task> handler)
where TReceiver : IApplicationMessageReceiver
where TReceiver : IMqttApplicationMessageReceiver
{
if (receiver == null) throw new ArgumentNullException(nameof(receiver));
@@ -90,7 +90,7 @@ namespace MQTTnet.Extensions.ManagedClient
}
public static TReceiver UseApplicationMessageReceivedHandler<TReceiver>(this TReceiver receiver, Action<MqttApplicationMessageReceivedEventArgs> handler)
where TReceiver : IApplicationMessageReceiver
where TReceiver : IMqttApplicationMessageReceiver
{
if (receiver == null) throw new ArgumentNullException(nameof(receiver));
@@ -103,7 +103,7 @@ namespace MQTTnet.Extensions.ManagedClient
}
public static TReceiver UseApplicationMessageReceivedHandler<TReceiver>(this TReceiver receiver, IMqttApplicationMessageReceivedHandler handler)
where TReceiver : IApplicationMessageReceiver
where TReceiver : IMqttApplicationMessageReceiver
{
if (receiver == null) throw new ArgumentNullException(nameof(receiver));
@@ -141,7 +141,7 @@ namespace MQTTnet.Extensions.ManagedClient
return client.UnsubscribeAsync(topicFilters);
}
public static async Task PublishAsync(this IApplicationMessagePublisher publisher, IEnumerable<MqttApplicationMessage> applicationMessages)
public static async Task PublishAsync(this IMqttApplicationMessagePublisher publisher, IEnumerable<MqttApplicationMessage> applicationMessages)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
@@ -152,7 +152,7 @@ namespace MQTTnet.Extensions.ManagedClient
}
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, MqttApplicationMessage applicationMessage)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, MqttApplicationMessage applicationMessage)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
@@ -160,7 +160,7 @@ namespace MQTTnet.Extensions.ManagedClient
return publisher.PublishAsync(applicationMessage, CancellationToken.None);
}
public static async Task PublishAsync(this IApplicationMessagePublisher publisher, params MqttApplicationMessage[] applicationMessages)
public static async Task PublishAsync(this IMqttApplicationMessagePublisher publisher, params MqttApplicationMessage[] applicationMessages)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
@@ -171,7 +171,7 @@ namespace MQTTnet.Extensions.ManagedClient
}
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, string topic)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, string topic)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (topic == null) throw new ArgumentNullException(nameof(topic));
@@ -180,7 +180,7 @@ namespace MQTTnet.Extensions.ManagedClient
.WithTopic(topic));
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, string topic, string payload)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, string topic, string payload)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (topic == null) throw new ArgumentNullException(nameof(topic));
@@ -190,7 +190,7 @@ namespace MQTTnet.Extensions.ManagedClient
.WithPayload(payload));
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (topic == null) throw new ArgumentNullException(nameof(topic));
@@ -201,7 +201,7 @@ namespace MQTTnet.Extensions.ManagedClient
.WithQualityOfServiceLevel(qualityOfServiceLevel));
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, bool retain)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, bool retain)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
if (topic == null) throw new ArgumentNullException(nameof(topic));
@@ -213,7 +213,7 @@ namespace MQTTnet.Extensions.ManagedClient
.WithRetainFlag(retain));
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder, CancellationToken cancellationToken)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder, CancellationToken cancellationToken)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
@@ -221,7 +221,7 @@ namespace MQTTnet.Extensions.ManagedClient
return publisher.PublishAsync(message, cancellationToken);
}
public static Task<MqttClientPublishResult> PublishAsync(this IApplicationMessagePublisher publisher, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder)
public static Task<MqttClientPublishResult> PublishAsync(this IMqttApplicationMessagePublisher publisher, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder)
{
if (publisher == null) throw new ArgumentNullException(nameof(publisher));
@@ -5,14 +5,14 @@ namespace MQTTnet.Extensions.ManagedClient
{
public static class MqttFactoryExtensions
{
public static IManagedMqttClient CreateManagedMqttClient(this IMqttFactory factory)
public static IManagedMqttClient CreateManagedMqttClient(this MqttFactory factory)
{
if (factory == null) throw new ArgumentNullException(nameof(factory));
return new ManagedMqttClient(factory.CreateMqttClient(), factory.DefaultLogger);
}
public static IManagedMqttClient CreateManagedMqttClient(this IMqttFactory factory, IMqttNetLogger logger)
public static IManagedMqttClient CreateManagedMqttClient(this MqttFactory factory, IMqttNetLogger logger)
{
if (factory == null) throw new ArgumentNullException(nameof(factory));
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -4,7 +4,7 @@ namespace MQTTnet.Extensions.WebSocket4Net
{
public static class MqttFactoryExtensions
{
public static IMqttFactory UseWebSocket4Net(this IMqttFactory mqttFactory)
public static MqttFactory UseWebSocket4Net(this MqttFactory mqttFactory)
{
if (mqttFactory == null) throw new ArgumentNullException(nameof(mqttFactory));
+1 -1
View File
@@ -8,7 +8,7 @@ namespace MQTTnet.Adapter
{
Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
Task StartAsync(IMqttServerOptions options);
Task StartAsync(MqttServerOptions options);
Task StopAsync();
}
}
@@ -6,7 +6,7 @@
/// Gets or sets the reason code.
/// Hint: MQTT 5 feature only.
/// </summary>
public MqttClientDisconnectReason ReasonCode { get; set; } = MqttClientDisconnectReason.NormalDisconnection;
public MqttClientDisconnectReason Reason { get; set; } = MqttClientDisconnectReason.NormalDisconnection;
/// <summary>
/// Gets or sets the reason string.
@@ -0,0 +1,29 @@
namespace MQTTnet.Client.Disconnecting
{
public sealed class MqttClientDisconnectOptionsBuilder
{
MqttClientDisconnectReason _reason = MqttClientDisconnectReason.NormalDisconnection;
string _reasonString;
public MqttClientDisconnectOptionsBuilder WithReasonString(string value)
{
_reasonString = value;
return this;
}
public MqttClientDisconnectOptionsBuilder WithReason(MqttClientDisconnectReason value)
{
_reason = value;
return this;
}
public MqttClientDisconnectOptions Build()
{
return new MqttClientDisconnectOptions
{
Reason = _reason,
ReasonString = _reasonString
};
}
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace MQTTnet.Client
{
public interface IMqttClient : IApplicationMessageReceiver, IApplicationMessagePublisher, IDisposable
public interface IMqttClient : IMqttApplicationMessageReceiver, IMqttApplicationMessagePublisher, IDisposable
{
bool IsConnected { get; }
@@ -1,28 +0,0 @@
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.LowLevelClient;
namespace MQTTnet.Client
{
public interface IMqttClientFactory
{
IMqttFactory UseClientAdapterFactory(IMqttClientAdapterFactory clientAdapterFactory);
ILowLevelMqttClient CreateLowLevelMqttClient();
ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger);
ILowLevelMqttClient CreateLowLevelMqttClient(IMqttClientAdapterFactory clientAdapterFactory);
ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactory);
IMqttClient CreateMqttClient();
IMqttClient CreateMqttClient(IMqttNetLogger logger);
IMqttClient CreateMqttClient(IMqttClientAdapterFactory adapterFactory);
IMqttClient CreateMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory adapterFactory);
}
}
@@ -150,13 +150,13 @@ namespace MQTTnet.Client
return client.DisconnectAsync(options, CancellationToken.None);
}
public static Task DisconnectAsync(this IMqttClient client, MqttClientDisconnectReason reasonCode, string reasonString = null)
public static Task DisconnectAsync(this IMqttClient client, MqttClientDisconnectReason reason, string reasonString = null)
{
if (client == null) throw new ArgumentNullException(nameof(client));
return client.DisconnectAsync(new MqttClientDisconnectOptions
{
ReasonCode = reasonCode,
Reason = reason,
ReasonString = reasonString
}, CancellationToken.None);
}
@@ -6,14 +6,14 @@ namespace MQTTnet.Formatter
{
public sealed class MqttConnAckPacketFactory
{
public MqttConnAckPacket Create(MqttConnectionValidatorContext connectionValidatorContext)
public MqttConnAckPacket Create(ValidatingMqttClientConnectionEventArgs clientConnectionValidationEventArgs)
{
if (connectionValidatorContext == null) throw new ArgumentNullException(nameof(connectionValidatorContext));
if (clientConnectionValidationEventArgs == null) throw new ArgumentNullException(nameof(clientConnectionValidationEventArgs));
var connAckPacket = new MqttConnAckPacket
{
ReturnCode = MqttConnectReasonCodeConverter.ToConnectReturnCode(connectionValidatorContext.ReasonCode),
ReasonCode = connectionValidatorContext.ReasonCode,
ReturnCode = MqttConnectReasonCodeConverter.ToConnectReturnCode(clientConnectionValidationEventArgs.ReasonCode),
ReasonCode = clientConnectionValidationEventArgs.ReasonCode,
Properties =
{
RetainAvailable = true,
@@ -22,17 +22,17 @@ namespace MQTTnet.Formatter
TopicAliasMaximum = ushort.MaxValue,
WildcardSubscriptionAvailable = true,
AuthenticationMethod = connectionValidatorContext.AuthenticationMethod,
AuthenticationData = connectionValidatorContext.ResponseAuthenticationData,
AssignedClientIdentifier = connectionValidatorContext.AssignedClientIdentifier,
ReasonString = connectionValidatorContext.ReasonString,
ServerReference = connectionValidatorContext.ServerReference
AuthenticationMethod = clientConnectionValidationEventArgs.AuthenticationMethod,
AuthenticationData = clientConnectionValidationEventArgs.ResponseAuthenticationData,
AssignedClientIdentifier = clientConnectionValidationEventArgs.AssignedClientIdentifier,
ReasonString = clientConnectionValidationEventArgs.ReasonString,
ServerReference = clientConnectionValidationEventArgs.ServerReference
}
};
if (connectionValidatorContext.ResponseUserProperties != null)
if (clientConnectionValidationEventArgs.ResponseUserProperties != null)
{
connAckPacket.Properties.UserProperties.AddRange(connectionValidatorContext.ResponseUserProperties);
connAckPacket.Properties.UserProperties.AddRange(clientConnectionValidationEventArgs.ResponseUserProperties);
}
return connAckPacket;
@@ -16,7 +16,7 @@ namespace MQTTnet.Formatter
}
else
{
packet.ReasonCode = (MqttDisconnectReasonCode) clientDisconnectOptions.ReasonCode;
packet.ReasonCode = (MqttDisconnectReasonCode) clientDisconnectOptions.Reason;
}
return packet;
@@ -4,7 +4,7 @@ using MQTTnet.Client.Publishing;
namespace MQTTnet
{
public interface IApplicationMessagePublisher
public interface IMqttApplicationMessagePublisher
{
Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken = default);
}
@@ -4,7 +4,7 @@ using MQTTnet.Client.Receiving;
namespace MQTTnet
{
public interface IApplicationMessageReceiver
public interface IMqttApplicationMessageReceiver
{
/// <summary>
/// Gets or sets the application message received handler that is fired every time a new message is received on the client's subscriptions.
-15
View File
@@ -1,15 +0,0 @@
using System.Collections.Generic;
using MQTTnet.Client;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Server;
namespace MQTTnet
{
public interface IMqttFactory : IMqttClientFactory, IMqttServerFactory
{
IMqttNetLogger DefaultLogger { get; }
IDictionary<object, object> Properties { get; }
}
}
@@ -31,7 +31,7 @@ namespace MQTTnet.Implementations
public bool TreatSocketOpeningErrorAsWarning { get; set; }
public Task StartAsync(IMqttServerOptions options)
public Task StartAsync(MqttServerOptions options)
{
if (_cancellationTokenSource != null) throw new InvalidOperationException("Server is already started.");
+16 -1
View File
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MQTTnet.Internal
{
public sealed class AsyncEvent<TEventArgs>
public sealed class AsyncEvent<TEventArgs> where TEventArgs : EventArgs
{
readonly List<Func<TEventArgs, Task>> _handlers = new List<Func<TEventArgs, Task>>();
@@ -29,5 +30,19 @@ namespace MQTTnet.Internal
await handler.Invoke(eventArgs);
}
}
public async Task<TEventArgs> InvokeAsync(Func<TEventArgs> eventArgsProvider)
{
if (eventArgsProvider == null) throw new ArgumentNullException(nameof(eventArgsProvider));
if (!_handlers.Any())
{
return default;
}
var eventArgs = eventArgsProvider.Invoke();
await InvokeAsync(eventArgs).ConfigureAwait(false);
return eventArgs;
}
}
}
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=server_005Coptions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=server_005Cstatus/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+20 -14
View File
@@ -6,6 +6,7 @@ using MQTTnet.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Subscribing;
using MQTTnet.Client.Unsubscribing;
@@ -13,7 +14,7 @@ using MQTTnet.Diagnostics.Logger;
namespace MQTTnet
{
public sealed class MqttFactory : IMqttFactory
public sealed class MqttFactory
{
IMqttClientAdapterFactory _clientAdapterFactory;
@@ -29,14 +30,14 @@ namespace MQTTnet
public IMqttNetLogger DefaultLogger { get; }
public IList<Func<IMqttFactory, IMqttServerAdapter>> DefaultServerAdapters { get; } = new List<Func<IMqttFactory, IMqttServerAdapter>>
public IList<Func<MqttFactory, IMqttServerAdapter>> DefaultServerAdapters { get; } = new List<Func<MqttFactory, IMqttServerAdapter>>
{
factory => new MqttTcpServerAdapter(factory.DefaultLogger)
};
public IDictionary<object, object> Properties { get; } = new Dictionary<object, object>();
public IMqttFactory UseClientAdapterFactory(IMqttClientAdapterFactory clientAdapterFactory)
public MqttFactory UseClientAdapterFactory(IMqttClientAdapterFactory clientAdapterFactory)
{
_clientAdapterFactory = clientAdapterFactory ?? throw new ArgumentNullException(nameof(clientAdapterFactory));
return this;
@@ -96,42 +97,47 @@ namespace MQTTnet
return new MqttClient(clientAdapterFactory, logger);
}
public IMqttServer CreateMqttServer()
public MqttServer CreateMqttServer(MqttServerOptions options)
{
return CreateMqttServer(DefaultLogger);
return CreateMqttServer(options, DefaultLogger);
}
public IMqttServer CreateMqttServer(IMqttNetLogger logger)
public MqttServer CreateMqttServer(MqttServerOptions options, IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
var serverAdapters = DefaultServerAdapters.Select(a => a.Invoke(this));
return CreateMqttServer(serverAdapters, logger);
return CreateMqttServer(options, serverAdapters, logger);
}
public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> serverAdapters, IMqttNetLogger logger)
public MqttServer CreateMqttServer(MqttServerOptions options, IEnumerable<IMqttServerAdapter> serverAdapters, IMqttNetLogger logger)
{
if (serverAdapters == null) throw new ArgumentNullException(nameof(serverAdapters));
if (logger == null) throw new ArgumentNullException(nameof(logger));
return new MqttServer(serverAdapters, logger);
return new MqttServer(options, serverAdapters, logger);
}
public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> serverAdapters)
public MqttServer CreateMqttServer(MqttServerOptions options, IEnumerable<IMqttServerAdapter> serverAdapters)
{
if (serverAdapters == null) throw new ArgumentNullException(nameof(serverAdapters));
return new MqttServer(serverAdapters, DefaultLogger);
return new MqttServer(options, serverAdapters, DefaultLogger);
}
public MqttServerOptionsBuilder CreateServerOptionsBuilder()
{
return new MqttServerOptionsBuilder();
}
public MqttClientOptionsBuilder CreateClientOptionsBuilder()
{
return new MqttClientOptionsBuilder();
}
public MqttServerOptionsBuilder CreateServerOptionsBuilder()
public MqttClientDisconnectOptionsBuilder CreateClientDisconnectOptionsBuilder()
{
return new MqttServerOptionsBuilder();
return new MqttClientDisconnectOptionsBuilder();
}
public MqttClientSubscribeOptionsBuilder CreateSubscribeOptionsBuilder()
@@ -1,9 +0,0 @@
namespace MQTTnet.Server
{
public sealed class GetSubscribedMessagesFilter
{
public bool IsNewSubscription { get; set; }
public MqttTopicFilter TopicFilter { get; set; }
}
}
@@ -1,15 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttClientSession
{
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
string ClientId { get; }
Task StopAsync();
}
}
@@ -7,7 +7,7 @@ namespace MQTTnet.Server
{
public interface IMqttRetainedMessagesManager
{
Task Start(IMqttServerOptions options, IMqttNetLogger logger);
Task Start(MqttServerOptions options, IMqttNetLogger logger);
Task LoadMessagesAsync();
+3 -13
View File
@@ -1,23 +1,13 @@
using System;
using MQTTnet.Server.Status;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServer : IApplicationMessageReceiver, IApplicationMessagePublisher, IDisposable
public interface IMqttServer : IDisposable
{
bool IsStarted { get; }
IMqttServerStartedHandler StartedHandler { get; set; }
IMqttServerStoppedHandler StoppedHandler { get; set; }
IMqttServerClientConnectedHandler ClientConnectedHandler { get; set; }
IMqttServerClientDisconnectedHandler ClientDisconnectedHandler { get; set; }
IMqttServerClientSubscribedTopicHandler ClientSubscribedTopicHandler { get; set; }
IMqttServerClientUnsubscribedTopicHandler ClientUnsubscribedTopicHandler { get; set; }
IMqttServerOptions Options { get; }
Task<IList<IMqttClientStatus>> GetClientStatusAsync();
Task<IList<IMqttSessionStatus>> GetSessionStatusAsync();
@@ -27,7 +17,7 @@ namespace MQTTnet.Server
Task SubscribeAsync(string clientId, ICollection<MqttTopicFilter> topicFilters);
Task UnsubscribeAsync(string clientId, ICollection<string> topicFilters);
Task StartAsync(IMqttServerOptions options);
Task StartAsync();
Task StopAsync();
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerApplicationMessageInterceptor
{
Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerClientConnectedHandler
{
Task HandleClientConnectedAsync(MqttServerClientConnectedEventArgs eventArgs);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerClientDisconnectedHandler
{
Task HandleClientDisconnectedAsync(MqttServerClientDisconnectedEventArgs eventArgs);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerClientMessageQueueInterceptor
{
Task InterceptClientMessageQueueEnqueueAsync(MqttClientMessageQueueInterceptorContext context);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerClientSubscribedTopicHandler
{
Task HandleClientSubscribedTopicAsync(MqttServerClientSubscribedTopicEventArgs eventArgs);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerClientUnsubscribedTopicHandler
{
Task HandleClientUnsubscribedTopicAsync(MqttServerClientUnsubscribedTopicEventArgs eventArgs);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerConnectionValidator
{
Task ValidateConnectionAsync(MqttConnectionValidatorContext context);
}
}
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Server
{
public interface IMqttServerFactory
{
IList<Func<IMqttFactory, IMqttServerAdapter>> DefaultServerAdapters { get; }
IMqttServer CreateMqttServer();
IMqttServer CreateMqttServer(IMqttNetLogger logger);
IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters);
IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger);
}
}
@@ -1,35 +0,0 @@
using System;
namespace MQTTnet.Server
{
public interface IMqttServerOptions
{
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
string ClientId { get; }
bool EnablePersistentSessions { get; }
int MaxPendingMessagesPerClient { get; }
MqttPendingMessagesOverflowStrategy PendingMessagesOverflowStrategy { get; }
TimeSpan DefaultCommunicationTimeout { get; }
TimeSpan KeepAliveMonitorInterval { get; }
IMqttServerConnectionValidator ConnectionValidator { get; }
IMqttServerSubscriptionInterceptor SubscriptionInterceptor { get; }
IMqttServerUnsubscriptionInterceptor UnsubscriptionInterceptor { get; }
IMqttServerApplicationMessageInterceptor ApplicationMessageInterceptor { get; }
IMqttServerClientMessageQueueInterceptor ClientMessageQueueInterceptor { get; }
IMqttServerApplicationMessageInterceptor UndeliveredMessageInterceptor { get; }
MqttServerTcpEndpointOptions DefaultEndpointOptions { get; }
MqttServerTlsTcpEndpointOptions TlsEndpointOptions { get; }
IMqttServerStorage Storage { get; }
IMqttRetainedMessagesManager RetainedMessagesManager { get; }
}
}
@@ -1,10 +0,0 @@
using System;
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerStartedHandler
{
Task HandleServerStartedAsync(EventArgs eventArgs);
}
}
@@ -1,10 +0,0 @@
using System;
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerStoppedHandler
{
Task HandleServerStoppedAsync(EventArgs eventArgs);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerSubscriptionInterceptor
{
Task InterceptSubscriptionAsync(MqttSubscriptionInterceptorContext context);
}
}
@@ -1,9 +0,0 @@
using System.Threading.Tasks;
namespace MQTTnet.Server
{
public interface IMqttServerUnsubscriptionInterceptor
{
Task InterceptUnsubscriptionAsync(MqttUnsubscriptionInterceptorContext context);
}
}
@@ -1,9 +1,10 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading;
namespace MQTTnet.Server
{
public sealed class MqttApplicationMessageInterceptorContext
public sealed class InterceptingMqttClientPublishEventArgs : EventArgs
{
/// <summary>
/// Gets the client identifier.
@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading;
using MQTTnet.Server.Status;
namespace MQTTnet.Server
{
public sealed class MqttSubscriptionInterceptorContext
public sealed class InterceptingMqttClientSubscriptionEventArgs : EventArgs
{
/// <summary>
/// Gets the client identifier.
@@ -1,9 +1,10 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading;
namespace MQTTnet.Server
{
public sealed class MqttUnsubscriptionInterceptorContext
public sealed class InterceptingMqttClientUnsubscriptionEventArgs : EventArgs
{
/// <summary>
/// Gets the client identifier.
@@ -7,13 +7,13 @@ namespace MQTTnet.Server.Internal
{
public sealed class MqttApplicationMessageInterceptorInvoker
{
readonly IMqttServerOptions _serverOptions;
readonly MqttServerEventContainer _eventContainer;
readonly string _clientId;
readonly IDictionary<object, object> _sessionItems;
public MqttApplicationMessageInterceptorInvoker(IMqttServerOptions serverOptions, string clientId, IDictionary<object, object> sessionItems)
public MqttApplicationMessageInterceptorInvoker(MqttServerEventContainer eventContainer, string clientId, IDictionary<object, object> sessionItems)
{
_serverOptions = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
_eventContainer = eventContainer ?? throw new ArgumentNullException(nameof(eventContainer));
_clientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
_sessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
@@ -35,13 +35,7 @@ namespace MQTTnet.Server.Internal
ApplicationMessage = applicationMessage;
// Intercept.
var interceptor = _serverOptions.ApplicationMessageInterceptor;
if (interceptor == null)
{
return;
}
var interceptorContext = new MqttApplicationMessageInterceptorContext
var eventArgs = new InterceptingMqttClientPublishEventArgs
{
ClientId = _clientId,
ApplicationMessage = applicationMessage,
@@ -51,13 +45,13 @@ namespace MQTTnet.Server.Internal
CancellationToken = cancellationToken
};
await interceptor.InterceptApplicationMessagePublishAsync(interceptorContext).ConfigureAwait(false);
await _eventContainer.InterceptingClientPublishEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// Expose results.
ProcessPublish = interceptorContext.ProcessPublish && interceptorContext.ApplicationMessage != null;
CloseConnection = interceptorContext.CloseConnection;
Response = interceptorContext.Response;
ApplicationMessage = interceptorContext.ApplicationMessage;
ProcessPublish = eventArgs.ProcessPublish && eventArgs.ApplicationMessage != null;
CloseConnection = eventArgs.CloseConnection;
Response = eventArgs.Response;
ApplicationMessage = eventArgs.ApplicationMessage;
}
}
}
@@ -26,7 +26,7 @@ namespace MQTTnet.Server.Internal
readonly MqttApplicationMessageInterceptorInvoker _applicationMessageInterceptorInvoker;
readonly IMqttServerOptions _serverOptions;
readonly MqttServerOptions _serverOptions;
readonly MqttConnectPacket _connectPacket;
CancellationTokenSource _cancellationToken;
@@ -35,7 +35,8 @@ namespace MQTTnet.Server.Internal
MqttConnectPacket connectPacket,
IMqttChannelAdapter channelAdapter,
MqttClientSession session,
IMqttServerOptions serverOptions,
MqttServerOptions serverOptions,
MqttServerEventContainer eventContainer,
MqttClientSessionsManager sessionsManager,
IMqttNetLogger logger)
{
@@ -48,7 +49,7 @@ namespace MQTTnet.Server.Internal
Session = session ?? throw new ArgumentNullException(nameof(session));
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
_applicationMessageInterceptorInvoker = new MqttApplicationMessageInterceptorInvoker(_serverOptions, Id, Session.Items);
_applicationMessageInterceptorInvoker = new MqttApplicationMessageInterceptorInvoker(eventContainer, Id, Session.Items);
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttClientConnection));
@@ -132,7 +133,7 @@ namespace MQTTnet.Server.Internal
{
var willPublishPacket = _packetFactories.Publish.Create(Session.LatestConnectPacket);
var willApplicationMessage = _applicationMessageFactory.Create(willPublishPacket);
_ = _sessionsManager.DispatchPublishPacket(willApplicationMessage, this);
_ = _sessionsManager.DispatchPublishPacket(Id, willApplicationMessage);
Session.WillMessageSent = true;
}
@@ -433,7 +434,7 @@ namespace MQTTnet.Server.Internal
if (_applicationMessageInterceptorInvoker.ProcessPublish)
{
await _sessionsManager.DispatchPublishPacket(applicationMessage, this).ConfigureAwait(false);
await _sessionsManager.DispatchPublishPacket(Id, applicationMessage).ConfigureAwait(false);
}
switch (publishPacket.QualityOfServiceLevel)
@@ -496,7 +497,7 @@ namespace MQTTnet.Server.Internal
{
var disconnectOptions = new MqttClientDisconnectOptions
{
ReasonCode = reason,
Reason = reason,
ReasonString = reason.ToString()
};
@@ -1,7 +1,6 @@
using System;
using System.Threading;
using MQTTnet.Packets;
using MQTTnet.Server.Status;
namespace MQTTnet.Server.Internal
{
@@ -16,13 +16,13 @@ namespace MQTTnet.Server.Internal
readonly Dictionary<ushort, MqttPublishPacket> _unacknowledgedPublishPackets = new Dictionary<ushort, MqttPublishPacket>();
readonly IMqttServerOptions _serverOptions;
readonly MqttServerOptions _serverOptions;
readonly MqttClientSessionsManager _clientSessionsManager;
public MqttClientSession(string clientId,
IDictionary<object, object> items,
MqttServerEventDispatcher eventDispatcher,
IMqttServerOptions serverOptions,
MqttServerOptions serverOptions,
MqttServerEventContainer eventContainer,
IMqttRetainedMessagesManager retainedMessagesManager,
MqttClientSessionsManager clientSessionsManager)
{
@@ -31,25 +31,25 @@ namespace MQTTnet.Server.Internal
Id = clientId ?? throw new ArgumentNullException(nameof(clientId));
Items = items ?? throw new ArgumentNullException(nameof(items));
SubscriptionsManager = new MqttClientSubscriptionsManager(this, serverOptions, eventDispatcher, retainedMessagesManager);
SubscriptionsManager = new MqttClientSubscriptionsManager(this, serverOptions, eventContainer, retainedMessagesManager);
}
public event EventHandler Deleted;
public string Id { get; }
public MqttPacketIdentifierProvider PacketIdentifierProvider { get; } = new MqttPacketIdentifierProvider();
public DateTime CreatedTimestamp { get; } = DateTime.UtcNow;
//public bool IsCleanSession { get; set; } = true;
public MqttConnectPacket LatestConnectPacket { get; set; }
public MqttClientSubscriptionsManager SubscriptionsManager { get; }
public IDictionary<object, object> Items { get; }
public bool WillMessageSent { get; set; }
public long PendingDataPacketsCount => _packetBus.DataPacketsCount;
@@ -58,7 +58,7 @@ namespace MQTTnet.Server.Internal
{
_unacknowledgedPublishPackets.Remove(packetIdentifier);
}
public void EnqueuePacket(MqttPacketBusItem packetBusItem)
{
if (packetBusItem == null) throw new ArgumentNullException(nameof(packetBusItem));
@@ -75,19 +75,19 @@ namespace MQTTnet.Server.Internal
// TODO: Implement.
}
}
if (packetBusItem.Packet is MqttPublishPacket publishPacket)
{
if (publishPacket.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
{
_unacknowledgedPublishPackets[publishPacket.PacketIdentifier] = publishPacket;
}
_packetBus.Enqueue(packetBusItem, MqttPacketBusPartition.Data);
}
else if (packetBusItem.Packet is MqttPingReqPacket || packetBusItem.Packet is MqttPingRespPacket)
{
_packetBus.Enqueue(packetBusItem, MqttPacketBusPartition.Health);
_packetBus.Enqueue(packetBusItem, MqttPacketBusPartition.Health);
}
else
{
@@ -99,17 +99,17 @@ namespace MQTTnet.Server.Internal
{
return _packetBus.DequeueAsync(cancellationToken);
}
public Task DeleteAsync()
{
return _clientSessionsManager.DeleteSessionAsync(Id);
}
public void OnDeleted()
{
Deleted?.Invoke(this, EventArgs.Empty);
}
public void Recover()
{
// TODO: Keep the bus and only insert pending items again.
@@ -1,65 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Internal;
namespace MQTTnet.Server.Internal
{
public sealed class MqttClientSessionApplicationMessagesQueue : IDisposable
{
readonly AsyncQueue<MqttQueuedApplicationMessage> _messageQueue = new AsyncQueue<MqttQueuedApplicationMessage>();
readonly IMqttServerOptions _options;
public MqttClientSessionApplicationMessagesQueue(IMqttServerOptions options)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
}
public int Count => _messageQueue.Count;
public void Enqueue(MqttQueuedApplicationMessage queuedApplicationMessage)
{
if (queuedApplicationMessage == null) throw new ArgumentNullException(nameof(queuedApplicationMessage));
lock (_messageQueue)
{
if (_messageQueue.Count >= _options.MaxPendingMessagesPerClient)
{
if (_options.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropNewMessage)
{
return;
}
if (_options.PendingMessagesOverflowStrategy == MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage)
{
_messageQueue.TryDequeue();
}
}
_messageQueue.Enqueue(queuedApplicationMessage);
}
}
public async Task<MqttQueuedApplicationMessage> Dequeue(CancellationToken cancellationToken)
{
var dequeueResult = await _messageQueue.TryDequeueAsync(cancellationToken).ConfigureAwait(false);
if (!dequeueResult.IsSuccess)
{
return null;
}
return dequeueResult.Item;
}
public void Clear()
{
_messageQueue.Clear();
}
public void Dispose()
{
_messageQueue?.Dispose();
}
}
}
@@ -12,13 +12,11 @@ using MQTTnet.Formatter;
using MQTTnet.Internal;
using MQTTnet.Packets;
using MQTTnet.Protocol;
using MQTTnet.Server.Status;
namespace MQTTnet.Server.Internal
{
public sealed class MqttClientSessionsManager
public sealed class MqttClientSessionsManager : IDisposable
{
//readonly BlockingCollection<MqttPendingApplicationMessage> _messageQueue = new BlockingCollection<MqttPendingApplicationMessage>();
readonly MqttPacketFactories _packetFactories = new MqttPacketFactories();
readonly AsyncLock _createConnectionSyncRoot = new AsyncLock();
@@ -29,33 +27,27 @@ namespace MQTTnet.Server.Internal
readonly MqttConnAckPacketFactory _connAckPacketFactory = new MqttConnAckPacketFactory();
readonly MqttServerEventDispatcher _eventDispatcher;
readonly IMqttRetainedMessagesManager _retainedMessagesManager;
readonly IMqttServerOptions _options;
readonly MqttServerEventContainer _eventContainer;
readonly MqttServerOptions _options;
readonly MqttNetSourceLogger _logger;
readonly IMqttNetLogger _rootLogger;
public MqttClientSessionsManager(
IMqttServerOptions options,
MqttServerOptions options,
IMqttRetainedMessagesManager retainedMessagesManager,
MqttServerEventDispatcher eventDispatcher,
MqttServerEventContainer eventContainer,
IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttClientSessionsManager));
_rootLogger = logger;
_eventDispatcher = eventDispatcher ?? throw new ArgumentNullException(nameof(eventDispatcher));
_options = options ?? throw new ArgumentNullException(nameof(options));
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
_eventContainer = eventContainer ?? throw new ArgumentNullException(nameof(eventContainer));
}
// public void Start(CancellationToken cancellationToken)
// {
// Task.Run(() => TryProcessQueuedApplicationMessagesAsync(cancellationToken), cancellationToken).RunInBackground(_logger);
// }
async Task<MqttConnectPacket> ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
{
try
@@ -115,8 +107,14 @@ namespace MQTTnet.Server.Internal
await channelAdapter.SendPacketAsync(connAckPacket, cancellationToken).ConfigureAwait(false);
await _eventDispatcher.SafeNotifyClientConnectedAsync(connectPacket, channelAdapter).ConfigureAwait(false);
await _eventContainer.ClientConnectedEvent.InvokeAsync(() => new MqttServerClientConnectedEventArgs
{
ClientId = connectPacket.ClientId,
UserName = connectPacket.Username,
ProtocolVersion = channelAdapter.PacketFormatterAdapter.ProtocolVersion,
Endpoint = channelAdapter.Endpoint
}).ConfigureAwait(false);
await clientConnection.RunAsync().ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -151,11 +149,12 @@ namespace MQTTnet.Server.Internal
if (clientConnection.Id != null && !clientConnection.IsTakenOver)
{
// The event is fired at a separate place in case of a handover!
await _eventDispatcher.SafeNotifyClientDisconnectedAsync(
clientConnection.Id,
clientConnection.IsCleanDisconnect ? MqttClientDisconnectType.Clean : MqttClientDisconnectType.NotClean,
endpoint).ConfigureAwait(false);
await _eventContainer.ClientDisconnectedEvent.InvokeAsync(() => new MqttServerClientDisconnectedEventArgs
{
ClientId = clientConnection.Id,
DisconnectType = clientConnection.IsCleanDisconnect ? MqttClientDisconnectType.Clean : MqttClientDisconnectType.NotClean,
Endpoint = endpoint
}).ConfigureAwait(false);
}
}
@@ -328,12 +327,10 @@ namespace MQTTnet.Server.Internal
// }
// }
public async Task DispatchPublishPacket(MqttApplicationMessage applicationMessage, MqttClientConnection sender)
public async Task DispatchPublishPacket(string senderClientId, MqttApplicationMessage applicationMessage)
{
try
{
var senderClientId = sender?.Id ?? _options.ClientId;
// MqttPendingApplicationMessage pendingApplicationMessage;
// try
// {
@@ -381,8 +378,10 @@ namespace MQTTnet.Server.Internal
// }
// }
await _eventDispatcher.SafeNotifyApplicationMessageReceivedAsync(senderClientId, applicationMessage).ConfigureAwait(false);
// await _eventContainer.ApplicationMessageReceivedEvent.InvokeAsync(
// () => new MqttApplicationMessageReceivedEventArgs(senderClientId, applicationMessage, null, null))
// .ConfigureAwait(false);
if (applicationMessage.Retain)
{
await _retainedMessagesManager.HandleMessageAsync(senderClientId, applicationMessage).ConfigureAwait(false);
@@ -442,14 +441,15 @@ namespace MQTTnet.Server.Internal
if (deliveryCount == 0)
{
var undeliveredMessageInterceptor = _options.UndeliveredMessageInterceptor;
if (undeliveredMessageInterceptor == null)
{
return;
}
// The delegate signature is the same as for regular message interceptor. So the call is fine and just uses a different interceptor.
await InterceptApplicationMessageAsync(undeliveredMessageInterceptor, sender, applicationMessage).ConfigureAwait(false);
// TODO: Addd event for not delivered publish packets.
// var undeliveredMessageInterceptor = _options.UndeliveredMessageInterceptor;
// if (undeliveredMessageInterceptor == null)
// {
// return;
// }
//
// // The delegate signature is the same as for regular message interceptor. So the call is fine and just uses a different interceptor.
// await InterceptApplicationMessageAsync(undeliveredMessageInterceptor, sender, applicationMessage).ConfigureAwait(false);
}
}
catch (Exception exception)
@@ -458,22 +458,14 @@ namespace MQTTnet.Server.Internal
}
}
async Task<MqttConnectionValidatorContext> ValidateConnection(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter)
async Task<ValidatingMqttClientConnectionEventArgs> ValidateConnection(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter)
{
var context = new MqttConnectionValidatorContext(connectPacket, channelAdapter)
var context = new ValidatingMqttClientConnectionEventArgs(connectPacket, channelAdapter)
{
SessionItems = new ConcurrentDictionary<object, object>()
};
var connectionValidator = _options.ConnectionValidator;
if (connectionValidator == null)
{
context.ReasonCode = MqttConnectReasonCode.Success;
return context;
}
await connectionValidator.ValidateConnectionAsync(context).ConfigureAwait(false);
await _eventContainer.ValidatingClientConnectionEvent.InvokeAsync(context).ConfigureAwait(false);
// Check the client ID and set a random one if supported.
if (string.IsNullOrEmpty(connectPacket.ClientId) && channelAdapter.PacketFormatterAdapter.ProtocolVersion == MqttProtocolVersion.V500)
@@ -537,7 +529,12 @@ namespace MQTTnet.Server.Internal
if (existingConnection != null)
{
await _eventDispatcher.SafeNotifyClientDisconnectedAsync(existingConnection.Id, MqttClientDisconnectType.Takeover, existingConnection.Endpoint);
await _eventContainer.ClientDisconnectedEvent.InvokeAsync(() => new MqttServerClientDisconnectedEventArgs
{
ClientId = existingConnection.Id,
DisconnectType = MqttClientDisconnectType.Takeover,
Endpoint = existingConnection.Endpoint
}).ConfigureAwait(false);
existingConnection.IsTakenOver = true;
await existingConnection.StopAsync(MqttClientDisconnectReason.SessionTakenOver).ConfigureAwait(false);
@@ -547,38 +544,38 @@ namespace MQTTnet.Server.Internal
return connection;
}
async Task<MqttApplicationMessageInterceptorContext> InterceptApplicationMessageAsync(
IMqttServerApplicationMessageInterceptor interceptor,
MqttClientConnection clientConnection,
MqttApplicationMessage applicationMessage)
{
string senderClientId;
IDictionary<object, object> sessionItems;
var messageIsFromServer = clientConnection == null;
if (messageIsFromServer)
{
senderClientId = _options.ClientId;
sessionItems = _serverSessionItems;
}
else
{
senderClientId = clientConnection.Id;
sessionItems = clientConnection.Session.Items;
}
var interceptorContext = new MqttApplicationMessageInterceptorContext
{
ClientId = senderClientId,
SessionItems = sessionItems,
ProcessPublish = true,
ApplicationMessage = applicationMessage,
CloseConnection = false
};
await interceptor.InterceptApplicationMessagePublishAsync(interceptorContext).ConfigureAwait(false);
return interceptorContext;
}
// async Task<InterceptingMqttClientPublishEventArgs> InterceptApplicationMessageAsync(
// IMqttServerApplicationMessageInterceptor interceptor,
// MqttClientConnection clientConnection,
// MqttApplicationMessage applicationMessage)
// {
// string senderClientId;
// IDictionary<object, object> sessionItems;
//
// var messageIsFromServer = clientConnection == null;
// if (messageIsFromServer)
// {
// senderClientId = _options.ClientId;
// sessionItems = _serverSessionItems;
// }
// else
// {
// senderClientId = clientConnection.Id;
// sessionItems = clientConnection.Session.Items;
// }
//
// var interceptorContext = new InterceptingMqttClientPublishEventArgs
// {
// ClientId = senderClientId,
// SessionItems = sessionItems,
// ProcessPublish = true,
// ApplicationMessage = applicationMessage,
// CloseConnection = false
// };
//
// await interceptor.InterceptApplicationMessagePublishAsync(interceptorContext).ConfigureAwait(false);
// return interceptorContext;
// }
MqttClientSession GetClientSession(string clientId)
{
@@ -600,6 +597,7 @@ namespace MQTTnet.Server.Internal
channelAdapter,
session,
_options,
_eventContainer,
this,
_rootLogger);
}
@@ -609,10 +607,25 @@ namespace MQTTnet.Server.Internal
return new MqttClientSession(
clientId,
sessionItems,
_eventDispatcher,
_options,
_eventContainer,
_retainedMessagesManager,
this);
}
public void Dispose()
{
_createConnectionSyncRoot?.Dispose();
foreach (var clientConnection in _clientConnections.Values)
{
clientConnection.Dispose();
}
foreach (var session in _clientSessions.Values)
{
session.Dispose();
}
}
}
}
@@ -5,7 +5,6 @@ using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Packets;
using MQTTnet.Protocol;
using MQTTnet.Server.Status;
namespace MQTTnet.Server.Internal
{
@@ -18,19 +17,19 @@ namespace MQTTnet.Server.Internal
readonly Dictionary<string, MqttSubscription> _subscriptions = new Dictionary<string, MqttSubscription>(4096);
readonly MqttClientSession _clientSession;
readonly IMqttServerOptions _options;
readonly MqttServerEventDispatcher _eventDispatcher;
readonly MqttServerOptions _options;
readonly MqttServerEventContainer _eventContainer;
readonly IMqttRetainedMessagesManager _retainedMessagesManager;
public MqttClientSubscriptionsManager(
MqttClientSession clientSession,
IMqttServerOptions serverOptions,
MqttServerEventDispatcher eventDispatcher,
MqttServerOptions serverOptions,
MqttServerEventContainer eventContainer,
IMqttRetainedMessagesManager retainedMessagesManager)
{
_clientSession = clientSession ?? throw new ArgumentNullException(nameof(clientSession));
_options = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
_eventDispatcher = eventDispatcher ?? throw new ArgumentNullException(nameof(eventDispatcher));
_eventContainer = eventContainer ?? throw new ArgumentNullException(nameof(eventContainer));
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
}
@@ -57,7 +56,7 @@ namespace MQTTnet.Server.Internal
}
else
{
result.ReturnCodes.Add((MqttSubscribeReturnCode)interceptorContext.Response.ReasonCode);
result.ReturnCodes.Add((MqttSubscribeReturnCode) interceptorContext.Response.ReasonCode);
result.ReasonCodes.Add(interceptorContext.Response.ReasonCode);
}
@@ -75,16 +74,18 @@ namespace MQTTnet.Server.Internal
if (interceptorContext.ProcessSubscription)
{
var subscription = CreateSubscription(
var createSubscriptionResult = CreateSubscription(
finalTopicFilter,
subscribePacket.Properties?.SubscriptionIdentifier ?? 0,
interceptorContext.Response.ReasonCode);
await _eventDispatcher
.SafeNotifyClientSubscribedTopicAsync(_clientSession.Id, finalTopicFilter)
.ConfigureAwait(false);
await _eventContainer.ClientSubscribedTopicEvent.InvokeAsync(() => new MqttServerClientSubscribedTopicEventArgs
{
ClientId = _clientSession.Id,
TopicFilter = finalTopicFilter
}).ConfigureAwait(false);
FilterRetainedApplicationMessages(retainedApplicationMessages, subscription, result);
FilterRetainedApplicationMessages(retainedApplicationMessages, createSubscriptionResult, result);
}
}
@@ -134,7 +135,11 @@ namespace MQTTnet.Server.Internal
foreach (var topicFilter in unsubscribePacket.TopicFilters)
{
await _eventDispatcher.SafeNotifyClientUnsubscribedTopicAsync(_clientSession.Id, topicFilter).ConfigureAwait(false);
await _eventContainer.ClientUnsubscribedTopicEvent.InvokeAsync(() => new MqttServerClientUnsubscribedTopicEventArgs
{
ClientId = _clientSession.Id,
TopicFilter = topicFilter
}).ConfigureAwait(false);
}
return result;
@@ -201,7 +206,14 @@ namespace MQTTnet.Server.Internal
};
}
MqttSubscription CreateSubscription(MqttTopicFilter topicFilter, uint subscriptionIdentifier, MqttSubscribeReasonCode reasonCode)
public sealed class CreateSubscriptionResult
{
public MqttSubscription Subscription { get; set; }
public bool IsNewSubscription { get; set; }
}
CreateSubscriptionResult CreateSubscription(MqttTopicFilter topicFilter, uint subscriptionIdentifier, MqttSubscribeReasonCode reasonCode)
{
var subscription = new MqttSubscription
{
@@ -229,10 +241,12 @@ namespace MQTTnet.Server.Internal
throw new InvalidOperationException();
}
bool isNewSubscription;
_subscriptionsLock.EnterWriteLock();
try
{
subscription.IsNewSubscription = !_subscriptions.ContainsKey(topicFilter.Topic);
isNewSubscription = !_subscriptions.ContainsKey(topicFilter.Topic);
_subscriptions[topicFilter.Topic] = subscription;
}
finally
@@ -240,11 +254,15 @@ namespace MQTTnet.Server.Internal
_subscriptionsLock.ExitWriteLock();
}
return subscription;
return new CreateSubscriptionResult
{
IsNewSubscription = isNewSubscription,
Subscription = subscription
};
}
static void FilterRetainedApplicationMessages(IList<MqttApplicationMessage> retainedApplicationMessages,
MqttSubscription mqttSubscription, MqttSubscribeResult mqttSubscribeResult)
static void FilterRetainedApplicationMessages(IList<MqttApplicationMessage> retainedApplicationMessages, CreateSubscriptionResult createSubscriptionResult,
MqttSubscribeResult subscribeResult)
{
for (var i = retainedApplicationMessages.Count - 1; i >= 0; i--)
{
@@ -254,20 +272,20 @@ namespace MQTTnet.Server.Internal
continue;
}
if (mqttSubscription.RetainHandling == MqttRetainHandling.DoNotSendOnSubscribe)
if (createSubscriptionResult.Subscription.RetainHandling == MqttRetainHandling.DoNotSendOnSubscribe)
{
// This is a MQTT V5+ feature.
continue;
}
if (mqttSubscription.RetainHandling == MqttRetainHandling.SendAtSubscribeIfNewSubscriptionOnly &&
!mqttSubscription.IsNewSubscription)
if (createSubscriptionResult.Subscription.RetainHandling == MqttRetainHandling.SendAtSubscribeIfNewSubscriptionOnly &&
!createSubscriptionResult.IsNewSubscription)
{
// This is a MQTT V5+ feature.
continue;
}
if (MqttTopicFilterComparer.Compare(retainedApplicationMessage.Topic, mqttSubscription.Topic) !=
if (MqttTopicFilterComparer.Compare(retainedApplicationMessage.Topic, createSubscriptionResult.Subscription.Topic) !=
MqttTopicFilterCompareResult.IsMatch)
{
continue;
@@ -277,23 +295,23 @@ namespace MQTTnet.Server.Internal
{
ApplicationMessage = retainedApplicationMessage,
IsRetainedMessage = true,
SubscriptionQualityOfServiceLevel = mqttSubscription.GrantedQualityOfServiceLevel
SubscriptionQualityOfServiceLevel = createSubscriptionResult.Subscription.GrantedQualityOfServiceLevel
};
if (mqttSubscription.Identifier > 0)
if (createSubscriptionResult.Subscription.Identifier > 0)
{
queuedApplicationMessage.SubscriptionIdentifiers = new List<uint> {mqttSubscription.Identifier};
queuedApplicationMessage.SubscriptionIdentifiers = new List<uint> {createSubscriptionResult.Subscription.Identifier};
}
mqttSubscribeResult.RetainedApplicationMessages.Add(queuedApplicationMessage);
subscribeResult.RetainedApplicationMessages.Add(queuedApplicationMessage);
retainedApplicationMessages[i] = null;
}
}
async Task<MqttSubscriptionInterceptorContext> InterceptSubscribe(MqttTopicFilter topicFilter, CancellationToken cancellationToken)
async Task<InterceptingMqttClientSubscriptionEventArgs> InterceptSubscribe(MqttTopicFilter topicFilter, CancellationToken cancellationToken)
{
var context = new MqttSubscriptionInterceptorContext
var subscriptionReceivedEventArgs = new InterceptingMqttClientSubscriptionEventArgs
{
ClientId = _clientSession.Id,
TopicFilter = topicFilter,
@@ -304,36 +322,32 @@ namespace MQTTnet.Server.Internal
if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
{
context.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS0;
subscriptionReceivedEventArgs.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS0;
}
else if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce)
{
context.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS1;
subscriptionReceivedEventArgs.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS1;
}
else if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.ExactlyOnce)
{
context.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS2;
subscriptionReceivedEventArgs.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS2;
}
if (topicFilter.Topic.StartsWith("$share/"))
{
context.Response.ReasonCode = MqttSubscribeReasonCode.SharedSubscriptionsNotSupported;
subscriptionReceivedEventArgs.Response.ReasonCode = MqttSubscribeReasonCode.SharedSubscriptionsNotSupported;
}
else
{
var interceptor = _options.SubscriptionInterceptor;
if (interceptor != null)
{
await interceptor.InterceptSubscriptionAsync(context).ConfigureAwait(false);
}
await _eventContainer.InterceptingClientSubscriptionEvent.InvokeAsync(subscriptionReceivedEventArgs).ConfigureAwait(false);
}
return context;
return subscriptionReceivedEventArgs;
}
async Task<MqttUnsubscriptionInterceptorContext> InterceptUnsubscribe(string topicFilter, MqttSubscription mqttSubscription, CancellationToken cancellationToken)
async Task<InterceptingMqttClientUnsubscriptionEventArgs> InterceptUnsubscribe(string topicFilter, MqttSubscription mqttSubscription, CancellationToken cancellationToken)
{
var context = new MqttUnsubscriptionInterceptorContext
var clientUnsubscribingTopicEventArgs = new InterceptingMqttClientUnsubscriptionEventArgs
{
ClientId = _clientSession.Id,
Topic = topicFilter,
@@ -343,22 +357,16 @@ namespace MQTTnet.Server.Internal
if (mqttSubscription == null)
{
context.Response.ReasonCode = MqttUnsubscribeReasonCode.NoSubscriptionExisted;
clientUnsubscribingTopicEventArgs.Response.ReasonCode = MqttUnsubscribeReasonCode.NoSubscriptionExisted;
}
else
{
context.Response.ReasonCode = MqttUnsubscribeReasonCode.Success;
clientUnsubscribingTopicEventArgs.Response.ReasonCode = MqttUnsubscribeReasonCode.Success;
}
var interceptor = _options.UnsubscriptionInterceptor;
if (interceptor == null)
{
return context;
}
await _eventContainer.InterceptingClientUnsubscriptionEvent.InvokeAsync(clientUnsubscribingTopicEventArgs).ConfigureAwait(false);
await interceptor.InterceptUnsubscriptionAsync(context).ConfigureAwait(false);
return context;
return clientUnsubscribingTopicEventArgs;
}
static MqttQualityOfServiceLevel GetEffectiveQoS(MqttQualityOfServiceLevel qosLevel, ICollection<MqttQualityOfServiceLevel> subscribedQoSLevels)
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Implementations;
using MQTTnet.Internal;
@@ -16,10 +15,10 @@ namespace MQTTnet.Server.Internal
readonly Dictionary<string, MqttApplicationMessage> _messages = new Dictionary<string, MqttApplicationMessage>(4096);
MqttNetSourceLogger _logger;
IMqttServerOptions _options;
MqttServerOptions _options;
// TODO: Get rid of the logger here!
public Task Start(IMqttServerOptions options, IMqttNetLogger logger)
public Task Start(MqttServerOptions options, IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttRetainedMessagesManager));
@@ -0,0 +1,154 @@
using System;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Internal;
namespace MQTTnet.Server.Internal
{
public sealed class MqttServerEventContainer
{
readonly MqttNetSourceLogger _logger;
public MqttServerEventContainer(IMqttNetLogger logger)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttServerEventContainer));
}
public AsyncEvent<InterceptingMqttClientSubscriptionEventArgs> InterceptingClientSubscriptionEvent { get; } = new AsyncEvent<InterceptingMqttClientSubscriptionEventArgs>();
public AsyncEvent<InterceptingMqttClientUnsubscriptionEventArgs> InterceptingClientUnsubscriptionEvent { get; } = new AsyncEvent<InterceptingMqttClientUnsubscriptionEventArgs>();
public AsyncEvent<InterceptingMqttClientPublishEventArgs> InterceptingClientPublishEvent { get; } = new AsyncEvent<InterceptingMqttClientPublishEventArgs>();
public AsyncEvent<ValidatingMqttClientConnectionEventArgs> ValidatingClientConnectionEvent { get; } = new AsyncEvent<ValidatingMqttClientConnectionEventArgs>();
public AsyncEvent<MqttServerClientConnectedEventArgs> ClientConnectedEvent { get; } = new AsyncEvent<MqttServerClientConnectedEventArgs>();
public AsyncEvent<MqttServerClientDisconnectedEventArgs> ClientDisconnectedEvent { get; } = new AsyncEvent<MqttServerClientDisconnectedEventArgs>();
public AsyncEvent<MqttServerClientSubscribedTopicEventArgs> ClientSubscribedTopicEvent { get; } = new AsyncEvent<MqttServerClientSubscribedTopicEventArgs>();
public AsyncEvent<MqttServerClientUnsubscribedTopicEventArgs> ClientUnsubscribedTopicEvent { get; } = new AsyncEvent<MqttServerClientUnsubscribedTopicEventArgs>();
public AsyncEvent<PreparingMqttClientSessionEventArgs> PreparingClientSessionEvent { get; } = new AsyncEvent<PreparingMqttClientSessionEventArgs>();
public AsyncEvent<EventArgs> StartedEvent { get; } = new AsyncEvent<EventArgs>();
public AsyncEvent<EventArgs> StoppedEvent { get; } = new AsyncEvent<EventArgs>();
// public async Task SafeNotifyClientConnectedAsync(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter)
// {
// try
// {
// var eventArgs = new MqttServerClientConnectedEventArgs
// {
// ClientId = connectPacket.ClientId,
// UserName = connectPacket.Username,
// ProtocolVersion = channelAdapter.PacketFormatterAdapter.ProtocolVersion,
// Endpoint = channelAdapter.Endpoint
// };
//
// var handler = ClientConnectedHandler;
// if (handler != null)
// {
// await handler.HandleClientConnectedAsync(eventArgs).ConfigureAwait(false);
// }
//
// await ClientConnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// }
// catch (Exception exception)
// {
// _logger.Error(exception, "Error while handling custom 'ClientConnected' event.");
// }
// }
// public async Task SafeNotifyClientDisconnectedAsync(string clientId, MqttClientDisconnectType disconnectType, string endpoint)
// {
// try
// {
// var eventArgs = new MqttServerClientDisconnectedEventArgs
// {
// ClientId = clientId,
// DisconnectType = disconnectType,
// Endpoint = endpoint
// };
//
// var handler = ClientDisconnectedHandler;
// if (handler != null)
// {
// await handler.HandleClientDisconnectedAsync(eventArgs).ConfigureAwait(false);
// }
//
// await ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// }
// catch (Exception exception)
// {
// _logger.Error(exception, "Error while handling custom 'ClientDisconnected' event.");
// }
// }
// public async Task SafeNotifyClientSubscribedTopicAsync(string clientId, MqttTopicFilter topicFilter)
// {
// try
// {
// var eventArgs = new MqttServerClientSubscribedTopicEventArgs
// {
// ClientId = clientId,
// TopicFilter = topicFilter
// };
//
// var handler = ClientSubscribedTopicHandler;
// if (handler != null)
// {
// await handler.HandleClientSubscribedTopicAsync(eventArgs).ConfigureAwait(false);
// }
//
// await ClientSubscribedTopicEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// }
// catch (Exception exception)
// {
// _logger.Error(exception, "Error while handling custom 'ClientSubscribedTopic' event.");
// }
// }
// public async Task SafeNotifyClientUnsubscribedTopicAsync(string clientId, string topicFilter)
// {
// try
// {
// var eventArgs = new MqttServerClientUnsubscribedTopicEventArgs
// {
// ClientId = clientId,
// TopicFilter = topicFilter
// };
//
// var handler = ClientUnsubscribedTopicHandler;
// if (handler != null)
// {
// await handler.HandleClientUnsubscribedTopicAsync(eventArgs).ConfigureAwait(false);
// }
//
// await ClientUnsubscribedTopicEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// }
// catch (Exception exception)
// {
// _logger.Error(exception, "Error while handling custom 'ClientUnsubscribedTopic' event.");
// }
// }
// public async Task SafeNotifyApplicationMessageReceivedAsync(string senderClientId, MqttApplicationMessage applicationMessage)
// {
// try
// {
// var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientId, applicationMessage, null, null);
//
// var handler = ApplicationMessageReceivedHandler;
// if (handler != null)
// {
// await handler.HandleApplicationMessageReceivedAsync(eventArgs).ConfigureAwait(false);
// }
//
// await ApplicationMessageReceivedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// }
// catch (Exception exception)
// {
// _logger.Error(exception, "Error while handling custom 'ApplicationMessageReceived' event.");
// }
// }
}
}
@@ -1,161 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Adapter;
using MQTTnet.Client.Receiving;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Internal;
using MQTTnet.Packets;
namespace MQTTnet.Server.Internal
{
public sealed class MqttServerEventDispatcher
{
readonly MqttNetSourceLogger _logger;
public MqttServerEventDispatcher(IMqttNetLogger logger)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttServerEventDispatcher));
}
public AsyncEvent<MqttServerClientConnectedEventArgs> ClientConnectedEvent { get; } = new AsyncEvent<MqttServerClientConnectedEventArgs>();
public AsyncEvent<MqttServerClientDisconnectedEventArgs> ClientDisconnectedEvent { get; } = new AsyncEvent<MqttServerClientDisconnectedEventArgs>();
public AsyncEvent<MqttServerClientSubscribedTopicEventArgs> ClientSubscribedTopicEvent { get; } = new AsyncEvent<MqttServerClientSubscribedTopicEventArgs>();
public AsyncEvent<MqttServerClientUnsubscribedTopicEventArgs> ClientUnsubscribedTopicEvent { get; } = new AsyncEvent<MqttServerClientUnsubscribedTopicEventArgs>();
public AsyncEvent<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceivedEvent { get; } = new AsyncEvent<MqttApplicationMessageReceivedEventArgs>();
public IMqttServerClientConnectedHandler ClientConnectedHandler { get; set; }
public IMqttServerClientDisconnectedHandler ClientDisconnectedHandler { get; set; }
public IMqttServerClientSubscribedTopicHandler ClientSubscribedTopicHandler { get; set; }
public IMqttServerClientUnsubscribedTopicHandler ClientUnsubscribedTopicHandler { get; set; }
public IMqttApplicationMessageReceivedHandler ApplicationMessageReceivedHandler { get; set; }
public async Task SafeNotifyClientConnectedAsync(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter)
{
try
{
var eventArgs = new MqttServerClientConnectedEventArgs
{
ClientId = connectPacket.ClientId,
UserName = connectPacket.Username,
ProtocolVersion = channelAdapter.PacketFormatterAdapter.ProtocolVersion,
Endpoint = channelAdapter.Endpoint
};
var handler = ClientConnectedHandler;
if (handler != null)
{
await handler.HandleClientConnectedAsync(eventArgs).ConfigureAwait(false);
}
await ClientConnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while handling custom 'ClientConnected' event.");
}
}
public async Task SafeNotifyClientDisconnectedAsync(string clientId, MqttClientDisconnectType disconnectType, string endpoint)
{
try
{
var eventArgs = new MqttServerClientDisconnectedEventArgs
{
ClientId = clientId,
DisconnectType = disconnectType,
Endpoint = endpoint
};
var handler = ClientDisconnectedHandler;
if (handler != null)
{
await handler.HandleClientDisconnectedAsync(eventArgs).ConfigureAwait(false);
}
await ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while handling custom 'ClientDisconnected' event.");
}
}
public async Task SafeNotifyClientSubscribedTopicAsync(string clientId, MqttTopicFilter topicFilter)
{
try
{
var eventArgs = new MqttServerClientSubscribedTopicEventArgs
{
ClientId = clientId,
TopicFilter = topicFilter
};
var handler = ClientSubscribedTopicHandler;
if (handler != null)
{
await handler.HandleClientSubscribedTopicAsync(eventArgs).ConfigureAwait(false);
}
await ClientSubscribedTopicEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while handling custom 'ClientSubscribedTopic' event.");
}
}
public async Task SafeNotifyClientUnsubscribedTopicAsync(string clientId, string topicFilter)
{
try
{
var eventArgs = new MqttServerClientUnsubscribedTopicEventArgs
{
ClientId = clientId,
TopicFilter = topicFilter
};
var handler = ClientUnsubscribedTopicHandler;
if (handler != null)
{
await handler.HandleClientUnsubscribedTopicAsync(eventArgs).ConfigureAwait(false);
}
await ClientUnsubscribedTopicEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while handling custom 'ClientUnsubscribedTopic' event.");
}
}
public async Task SafeNotifyApplicationMessageReceivedAsync(string senderClientId, MqttApplicationMessage applicationMessage)
{
try
{
var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientId, applicationMessage, null, null);
var handler = ApplicationMessageReceivedHandler;
if (handler != null)
{
await handler.HandleApplicationMessageReceivedAsync(eventArgs).ConfigureAwait(false);
}
await ApplicationMessageReceivedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while handling custom 'ApplicationMessageReceived' event.");
}
}
}
}
@@ -10,11 +10,11 @@ namespace MQTTnet.Server.Internal
{
public sealed class MqttServerKeepAliveMonitor
{
readonly IMqttServerOptions _options;
readonly MqttServerOptions _options;
readonly MqttClientSessionsManager _sessionsManager;
readonly MqttNetSourceLogger _logger;
public MqttServerKeepAliveMonitor(IMqttServerOptions options, MqttClientSessionsManager sessionsManager, IMqttNetLogger logger)
public MqttServerKeepAliveMonitor(MqttServerOptions options, MqttClientSessionsManager sessionsManager, IMqttNetLogger logger)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_sessionsManager = sessionsManager ?? throw new ArgumentNullException(nameof(sessionsManager));
@@ -15,7 +15,5 @@ namespace MQTTnet.Server.Internal
public MqttQualityOfServiceLevel GrantedQualityOfServiceLevel { get; set; }
public uint Identifier { get; set; }
public bool IsNewSubscription { get; set; }
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttClientMessageQueueInterceptorDelegate : IMqttServerClientMessageQueueInterceptor
{
readonly Func<MqttClientMessageQueueInterceptorContext, Task> _callback;
public MqttClientMessageQueueInterceptorDelegate(Action<MqttClientMessageQueueInterceptorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttClientMessageQueueInterceptorDelegate(Func<MqttClientMessageQueueInterceptorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task InterceptClientMessageQueueEnqueueAsync(MqttClientMessageQueueInterceptorContext context)
{
return _callback(context);
}
}
}
@@ -1,18 +0,0 @@
using MQTTnet.Packets;
using MQTTnet.Server.Internal;
namespace MQTTnet.Server
{
public sealed class MqttPendingApplicationMessage
{
public MqttPendingApplicationMessage(MqttPublishPacket publishPacket, MqttClientConnection sender)
{
Sender = sender;
PublishPacket = publishPacket;
}
public MqttClientConnection Sender { get; }
public MqttPublishPacket PublishPacket { get; }
}
}
+57 -86
View File
@@ -1,9 +1,7 @@
using MQTTnet.Adapter;
using MQTTnet.Client.Publishing;
using MQTTnet.Client.Receiving;
using MQTTnet.Exceptions;
using MQTTnet.Protocol;
using MQTTnet.Server.Status;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -16,13 +14,12 @@ using MQTTnet.Server.Internal;
namespace MQTTnet.Server
{
public sealed class MqttServer : Disposable, IMqttServer
public class MqttServer : Disposable, IMqttServer
{
readonly AsyncEvent<EventArgs> _startedEvent = new AsyncEvent<EventArgs>();
readonly AsyncEvent<EventArgs> _stoppedEvent = new AsyncEvent<EventArgs>();
readonly MqttServerEventContainer _eventContainer;
readonly MqttServerEventDispatcher _eventDispatcher;
readonly ICollection<IMqttServerAdapter> _adapters;
readonly MqttServerOptions _options;
readonly IMqttNetLogger _rootLogger;
readonly MqttNetSourceLogger _logger;
@@ -31,98 +28,87 @@ namespace MQTTnet.Server
MqttServerKeepAliveMonitor _keepAliveMonitor;
CancellationTokenSource _cancellationTokenSource;
public MqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
public MqttServer(MqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
{
if (adapters == null) throw new ArgumentNullException(nameof(adapters));
_adapters = adapters.ToList();
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttServer));
_options = options;
_rootLogger = logger;
_eventDispatcher = new MqttServerEventDispatcher(logger);
_eventContainer = new MqttServerEventContainer(logger);
}
public bool IsStarted => _cancellationTokenSource != null;
public IMqttServerStartedHandler StartedHandler { get; set; }
public event Func<EventArgs, Task> StartedAsync
{
add => _startedEvent.AddHandler(value);
remove => _startedEvent.RemoveHandler(value);
add => _eventContainer.StartedEvent.AddHandler(value);
remove => _eventContainer.StartedEvent.RemoveHandler(value);
}
public IMqttServerStoppedHandler StoppedHandler { get; set; }
public event Func<EventArgs, Task> StoppedAsync
{
add => _stoppedEvent.AddHandler(value);
remove => _stoppedEvent.RemoveHandler(value);
add => _eventContainer.StoppedEvent.AddHandler(value);
remove => _eventContainer.StoppedEvent.RemoveHandler(value);
}
public IMqttServerClientConnectedHandler ClientConnectedHandler
public event Func<ValidatingMqttClientConnectionEventArgs, Task> ValidatingClientConnectionAsync
{
get => _eventDispatcher.ClientConnectedHandler;
set => _eventDispatcher.ClientConnectedHandler = value;
add => _eventContainer.ValidatingClientConnectionEvent.AddHandler(value);
remove => _eventContainer.ValidatingClientConnectionEvent.RemoveHandler(value);
}
public event Func<MqttServerClientConnectedEventArgs, Task> ClientConnectedAsync
{
add => _eventDispatcher.ClientConnectedEvent.AddHandler(value);
remove => _eventDispatcher.ClientConnectedEvent.RemoveHandler(value);
add => _eventContainer.ClientConnectedEvent.AddHandler(value);
remove => _eventContainer.ClientConnectedEvent.RemoveHandler(value);
}
public IMqttServerClientDisconnectedHandler ClientDisconnectedHandler
{
get => _eventDispatcher.ClientDisconnectedHandler;
set => _eventDispatcher.ClientDisconnectedHandler = value;
}
public event Func<MqttServerClientDisconnectedEventArgs, Task> ClientDisconnectedAsync
{
add => _eventDispatcher.ClientDisconnectedEvent.AddHandler(value);
remove => _eventDispatcher.ClientDisconnectedEvent.RemoveHandler(value);
add => _eventContainer.ClientDisconnectedEvent.AddHandler(value);
remove => _eventContainer.ClientDisconnectedEvent.RemoveHandler(value);
}
public IMqttServerClientSubscribedTopicHandler ClientSubscribedTopicHandler
public event Func<InterceptingMqttClientSubscriptionEventArgs, Task> InterceptingClientSubscriptionAsync
{
get => _eventDispatcher.ClientSubscribedTopicHandler;
set => _eventDispatcher.ClientSubscribedTopicHandler = value;
add => _eventContainer.InterceptingClientSubscriptionEvent.AddHandler(value);
remove => _eventContainer.InterceptingClientSubscriptionEvent.RemoveHandler(value);
}
public event Func<InterceptingMqttClientUnsubscriptionEventArgs, Task> InterceptingClientUnsubscriptionAsync
{
add => _eventContainer.InterceptingClientUnsubscriptionEvent.AddHandler(value);
remove => _eventContainer.InterceptingClientUnsubscriptionEvent.RemoveHandler(value);
}
public event Func<InterceptingMqttClientPublishEventArgs, Task> InterceptingClientPublishAsync
{
add => _eventContainer.InterceptingClientPublishEvent.AddHandler(value);
remove => _eventContainer.InterceptingClientPublishEvent.RemoveHandler(value);
}
public event Func<MqttServerClientSubscribedTopicEventArgs, Task> ClientSubscribedTopicAsync
{
add => _eventDispatcher.ClientSubscribedTopicEvent.AddHandler(value);
remove => _eventDispatcher.ClientSubscribedTopicEvent.RemoveHandler(value);
}
public IMqttServerClientUnsubscribedTopicHandler ClientUnsubscribedTopicHandler
{
get => _eventDispatcher.ClientUnsubscribedTopicHandler;
set => _eventDispatcher.ClientUnsubscribedTopicHandler = value;
add => _eventContainer.ClientSubscribedTopicEvent.AddHandler(value);
remove => _eventContainer.ClientSubscribedTopicEvent.RemoveHandler(value);
}
public event Func<MqttServerClientUnsubscribedTopicEventArgs, Task> ClientUnsubscribedTopicAsync
{
add => _eventDispatcher.ClientUnsubscribedTopicEvent.AddHandler(value);
remove => _eventDispatcher.ClientUnsubscribedTopicEvent.RemoveHandler(value);
}
public IMqttApplicationMessageReceivedHandler ApplicationMessageReceivedHandler
{
get => _eventDispatcher.ApplicationMessageReceivedHandler;
set => _eventDispatcher.ApplicationMessageReceivedHandler = value;
add => _eventContainer.ClientUnsubscribedTopicEvent.AddHandler(value);
remove => _eventContainer.ClientUnsubscribedTopicEvent.RemoveHandler(value);
}
public event Func<MqttApplicationMessageReceivedEventArgs, Task> ApplicationMessageReceivedAsync
public event Func<PreparingMqttClientSessionEventArgs, Task> PreparingClientSessionAsync
{
add => _eventDispatcher.ApplicationMessageReceivedEvent.AddHandler(value);
remove => _eventDispatcher.ApplicationMessageReceivedEvent.RemoveHandler(value);
add => _eventContainer.PreparingClientSessionEvent.AddHandler(value);
remove => _eventContainer.PreparingClientSessionEvent.RemoveHandler(value);
}
public IMqttServerOptions Options { get; private set; }
public bool IsStarted => _cancellationTokenSource != null;
public Task<IList<IMqttClientStatus>> GetClientStatusAsync()
{
ThrowIfDisposed();
@@ -182,7 +168,7 @@ namespace MQTTnet.Server
return _clientSessionsManager.UnsubscribeAsync(clientId, topicFilters);
}
public async Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
public async Task<MqttClientPublishResult> PublishAsync(string senderClientId, MqttApplicationMessage applicationMessage, CancellationToken cancellationToken = default)
{
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
@@ -192,47 +178,38 @@ namespace MQTTnet.Server
ThrowIfNotStarted();
await _clientSessionsManager.DispatchPublishPacket(applicationMessage, null);
await _clientSessionsManager.DispatchPublishPacket(senderClientId, applicationMessage);
return new MqttClientPublishResult();
}
public async Task StartAsync(IMqttServerOptions options)
public async Task StartAsync()
{
ThrowIfDisposed();
ThrowIfStarted();
Options = options ?? throw new ArgumentNullException(nameof(options));
_cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _cancellationTokenSource.Token;
_retainedMessagesManager = Options.RetainedMessagesManager ?? throw new MqttConfigurationException("options.RetainedMessagesManager should not be null.");
_retainedMessagesManager = _options.RetainedMessagesManager ?? throw new MqttConfigurationException("options.RetainedMessagesManager should not be null.");
await _retainedMessagesManager.Start(Options, _rootLogger).ConfigureAwait(false);
await _retainedMessagesManager.Start(_options, _rootLogger).ConfigureAwait(false);
await _retainedMessagesManager.LoadMessagesAsync().ConfigureAwait(false);
_clientSessionsManager = new MqttClientSessionsManager(Options, _retainedMessagesManager, _eventDispatcher, _rootLogger);
//_clientSessionsManager.Start(cancellationToken);
_keepAliveMonitor = new MqttServerKeepAliveMonitor(Options, _clientSessionsManager, _rootLogger);
_clientSessionsManager = new MqttClientSessionsManager(_options, _retainedMessagesManager, _eventContainer, _rootLogger);
_keepAliveMonitor = new MqttServerKeepAliveMonitor(_options, _clientSessionsManager, _rootLogger);
_keepAliveMonitor.Start(cancellationToken);
foreach (var adapter in _adapters)
{
adapter.ClientHandler = c => OnHandleClient(c, cancellationToken);
await adapter.StartAsync(Options).ConfigureAwait(false);
await adapter.StartAsync(_options).ConfigureAwait(false);
}
_logger.Info("Started.");
var startedHandler = StartedHandler;
if (startedHandler != null)
{
await startedHandler.HandleServerStartedAsync(EventArgs.Empty).ConfigureAwait(false);
}
await _startedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
await _eventContainer.StartedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
}
public async Task StopAsync()
@@ -267,13 +244,7 @@ namespace MQTTnet.Server
_retainedMessagesManager = null;
}
var stoppedHandler = StoppedHandler;
if (stoppedHandler != null)
{
await stoppedHandler.HandleServerStoppedAsync(EventArgs.Empty).ConfigureAwait(false);
}
await _stoppedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
await _eventContainer.StoppedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
}
protected override void Dispose(bool disposing)
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerApplicationMessageInterceptorDelegate : IMqttServerApplicationMessageInterceptor
{
readonly Func<MqttApplicationMessageInterceptorContext, Task> _callback;
public MqttServerApplicationMessageInterceptorDelegate(Action<MqttApplicationMessageInterceptorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerApplicationMessageInterceptorDelegate(Func<MqttApplicationMessageInterceptorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
{
return _callback(context);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerClientConnectedHandlerDelegate : IMqttServerClientConnectedHandler
{
readonly Func<MqttServerClientConnectedEventArgs, Task> _handler;
public MqttServerClientConnectedHandlerDelegate(Action<MqttServerClientConnectedEventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerClientConnectedHandlerDelegate(Func<MqttServerClientConnectedEventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleClientConnectedAsync(MqttServerClientConnectedEventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerClientDisconnectedHandlerDelegate : IMqttServerClientDisconnectedHandler
{
readonly Func<MqttServerClientDisconnectedEventArgs, Task> _handler;
public MqttServerClientDisconnectedHandlerDelegate(Action<MqttServerClientDisconnectedEventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerClientDisconnectedHandlerDelegate(Func<MqttServerClientDisconnectedEventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleClientDisconnectedAsync(MqttServerClientDisconnectedEventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,44 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
[Obsolete("Use MqttServerClientSubscribedTopicHandlerDelegate instead. This will be removed in a future version.")]
public sealed class MqttServerClientSubscribedHandlerDelegate : MqttServerClientSubscribedTopicHandlerDelegate
{
public MqttServerClientSubscribedHandlerDelegate(Action<MqttServerClientSubscribedTopicEventArgs> handler) : base(handler)
{
}
public MqttServerClientSubscribedHandlerDelegate(Func<MqttServerClientSubscribedTopicEventArgs, Task> handler) : base(handler)
{
}
}
public class MqttServerClientSubscribedTopicHandlerDelegate : IMqttServerClientSubscribedTopicHandler
{
readonly Func<MqttServerClientSubscribedTopicEventArgs, Task> _handler;
public MqttServerClientSubscribedTopicHandlerDelegate(Action<MqttServerClientSubscribedTopicEventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerClientSubscribedTopicHandlerDelegate(Func<MqttServerClientSubscribedTopicEventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleClientSubscribedTopicAsync(MqttServerClientSubscribedTopicEventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerClientUnsubscribedTopicHandlerDelegate : IMqttServerClientUnsubscribedTopicHandler
{
readonly Func<MqttServerClientUnsubscribedTopicEventArgs, Task> _handler;
public MqttServerClientUnsubscribedTopicHandlerDelegate(Action<MqttServerClientUnsubscribedTopicEventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerClientUnsubscribedTopicHandlerDelegate(Func<MqttServerClientUnsubscribedTopicEventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleClientUnsubscribedTopicAsync(MqttServerClientUnsubscribedTopicEventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerConnectionValidatorDelegate : IMqttServerConnectionValidator
{
readonly Func<MqttConnectionValidatorContext, Task> _callback;
public MqttServerConnectionValidatorDelegate(Action<MqttConnectionValidatorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerConnectionValidatorDelegate(Func<MqttConnectionValidatorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task ValidateConnectionAsync(MqttConnectionValidatorContext context)
{
return _callback(context);
}
}
}
+81 -179
View File
@@ -1,8 +1,6 @@
using MQTTnet.Client.Publishing;
using MQTTnet.Client.Receiving;
using MQTTnet.Protocol;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -10,102 +8,6 @@ namespace MQTTnet.Server
{
public static class MqttServerExtensions
{
public static IMqttServer UseClientConnectedHandler(this IMqttServer server, Func<MqttServerClientConnectedEventArgs, Task> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseClientConnectedHandler((IMqttServerClientConnectedHandler)null);
}
return server.UseClientConnectedHandler(new MqttServerClientConnectedHandlerDelegate(handler));
}
public static IMqttServer UseClientConnectedHandler(this IMqttServer server, Action<MqttServerClientConnectedEventArgs> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseClientConnectedHandler((IMqttServerClientConnectedHandler)null);
}
return server.UseClientConnectedHandler(new MqttServerClientConnectedHandlerDelegate(handler));
}
public static IMqttServer UseClientConnectedHandler(this IMqttServer server, IMqttServerClientConnectedHandler handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
server.ClientConnectedHandler = handler;
return server;
}
public static IMqttServer UseClientDisconnectedHandler(this IMqttServer server, Func<MqttServerClientDisconnectedEventArgs, Task> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseClientDisconnectedHandler((IMqttServerClientDisconnectedHandler)null);
}
return server.UseClientDisconnectedHandler(new MqttServerClientDisconnectedHandlerDelegate(handler));
}
public static IMqttServer UseClientDisconnectedHandler(this IMqttServer server, Action<MqttServerClientDisconnectedEventArgs> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseClientDisconnectedHandler((IMqttServerClientDisconnectedHandler)null);
}
return server.UseClientDisconnectedHandler(new MqttServerClientDisconnectedHandlerDelegate(handler));
}
public static IMqttServer UseClientDisconnectedHandler(this IMqttServer server, IMqttServerClientDisconnectedHandler handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
server.ClientDisconnectedHandler = handler;
return server;
}
public static IMqttServer UseApplicationMessageReceivedHandler(this IMqttServer server, Func<MqttApplicationMessageReceivedEventArgs, Task> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseApplicationMessageReceivedHandler((IMqttApplicationMessageReceivedHandler)null);
}
return server.UseApplicationMessageReceivedHandler(new MqttApplicationMessageReceivedHandlerDelegate(handler));
}
public static IMqttServer UseApplicationMessageReceivedHandler(this IMqttServer server, Action<MqttApplicationMessageReceivedEventArgs> handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (handler == null)
{
return server.UseApplicationMessageReceivedHandler((IMqttApplicationMessageReceivedHandler)null);
}
return server.UseApplicationMessageReceivedHandler(new MqttApplicationMessageReceivedHandlerDelegate(handler));
}
public static IMqttServer UseApplicationMessageReceivedHandler(this IMqttServer server, IMqttApplicationMessageReceivedHandler handler)
{
if (server == null) throw new ArgumentNullException(nameof(server));
server.ApplicationMessageReceivedHandler = handler;
return server;
}
public static Task SubscribeAsync(this IMqttServer server, string clientId, params MqttTopicFilter[] topicFilters)
{
if (server == null) throw new ArgumentNullException(nameof(server));
@@ -142,92 +44,92 @@ namespace MQTTnet.Server
return server.UnsubscribeAsync(clientId, topicFilters);
}
public static async Task PublishAsync(this IMqttServer server, IEnumerable<MqttApplicationMessage> applicationMessages)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
// public static async Task PublishAsync(this IMqttServer server, IEnumerable<MqttApplicationMessage> applicationMessages)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
//
// foreach (var applicationMessage in applicationMessages)
// {
// await server.PublishAsync(applicationMessage).ConfigureAwait(false);
// }
// }
foreach (var applicationMessage in applicationMessages)
{
await server.PublishAsync(applicationMessage).ConfigureAwait(false);
}
}
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, MqttApplicationMessage applicationMessage)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
//
// return server.PublishAsync(applicationMessage, CancellationToken.None);
// }
//
// public static async Task PublishAsync(this IMqttServer server, params MqttApplicationMessage[] applicationMessages)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
//
// foreach (var applicationMessage in applicationMessages)
// {
// await server.PublishAsync(applicationMessage, CancellationToken.None).ConfigureAwait(false);
// }
// }
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, MqttApplicationMessage applicationMessage)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (topic == null) throw new ArgumentNullException(nameof(topic));
//
// return server.PublishAsync(builder => builder
// .WithTopic(topic));
// }
return server.PublishAsync(applicationMessage, CancellationToken.None);
}
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (topic == null) throw new ArgumentNullException(nameof(topic));
//
// return server.PublishAsync(builder => builder
// .WithTopic(topic)
// .WithPayload(payload));
// }
public static async Task PublishAsync(this IMqttServer server, params MqttApplicationMessage[] applicationMessages)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (topic == null) throw new ArgumentNullException(nameof(topic));
//
// return server.PublishAsync(builder => builder
// .WithTopic(topic)
// .WithPayload(payload)
// .WithQualityOfServiceLevel(qualityOfServiceLevel));
// }
foreach (var applicationMessage in applicationMessages)
{
await server.PublishAsync(applicationMessage, CancellationToken.None).ConfigureAwait(false);
}
}
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, bool retain)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
// if (topic == null) throw new ArgumentNullException(nameof(topic));
//
// return server.PublishAsync(builder => builder
// .WithTopic(topic)
// .WithPayload(payload)
// .WithQualityOfServiceLevel(qualityOfServiceLevel)
// .WithRetainFlag(retain));
// }
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (topic == null) throw new ArgumentNullException(nameof(topic));
return server.PublishAsync(builder => builder
.WithTopic(topic));
}
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (topic == null) throw new ArgumentNullException(nameof(topic));
return server.PublishAsync(builder => builder
.WithTopic(topic)
.WithPayload(payload));
}
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (topic == null) throw new ArgumentNullException(nameof(topic));
return server.PublishAsync(builder => builder
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(qualityOfServiceLevel));
}
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, string topic, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, bool retain)
{
if (server == null) throw new ArgumentNullException(nameof(server));
if (topic == null) throw new ArgumentNullException(nameof(topic));
return server.PublishAsync(builder => builder
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(qualityOfServiceLevel)
.WithRetainFlag(retain));
}
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder, CancellationToken cancellationToken)
{
if (server == null) throw new ArgumentNullException(nameof(server));
var message = builder(new MqttApplicationMessageBuilder()).Build();
return server.PublishAsync(message, cancellationToken);
}
public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder)
{
if (server == null) throw new ArgumentNullException(nameof(server));
var message = builder(new MqttApplicationMessageBuilder()).Build();
return server.PublishAsync(message, CancellationToken.None);
}
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder, CancellationToken cancellationToken)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
//
// var message = builder(new MqttApplicationMessageBuilder()).Build();
// return server.PublishAsync(message, cancellationToken);
// }
//
// public static Task<MqttClientPublishResult> PublishAsync(this IMqttServer server, Func<MqttApplicationMessageBuilder, MqttApplicationMessageBuilder> builder)
// {
// if (server == null) throw new ArgumentNullException(nameof(server));
//
// var message = builder(new MqttApplicationMessageBuilder()).Build();
// return server.PublishAsync(message, CancellationToken.None);
// }
}
}
@@ -1,51 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
using MQTTnet.Internal;
namespace MQTTnet.Server
{
public sealed class MqttServerMultiThreadedApplicationMessageInterceptorDelegate : IMqttServerApplicationMessageInterceptor
{
readonly Func<MqttApplicationMessageInterceptorContext, Task> _callback;
public MqttServerMultiThreadedApplicationMessageInterceptorDelegate(Action<MqttApplicationMessageInterceptorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public Func<MqttApplicationMessageInterceptorContext, Exception, Task> ExceptionHandler { get; set; }
public MqttServerMultiThreadedApplicationMessageInterceptorDelegate(Func<MqttApplicationMessageInterceptorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
{
Task.Run(async () =>
{
try
{
await _callback.Invoke(context).ConfigureAwait(false);
}
catch (Exception exception)
{
var exceptionHandler = ExceptionHandler;
if (exceptionHandler != null)
{
await exceptionHandler.Invoke(context, exception).ConfigureAwait(false);
}
}
}).RunInBackground();
return PlatformAbstractionLayer.CompletedTask;
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerStartedHandlerDelegate : IMqttServerStartedHandler
{
readonly Func<EventArgs, Task> _handler;
public MqttServerStartedHandlerDelegate(Action<EventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerStartedHandlerDelegate(Func<EventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleServerStartedAsync(EventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerStoppedHandlerDelegate : IMqttServerStoppedHandler
{
readonly Func<EventArgs, Task> _handler;
public MqttServerStoppedHandlerDelegate(Action<EventArgs> handler)
{
if (handler == null) throw new ArgumentNullException(nameof(handler));
_handler = eventArgs =>
{
handler(eventArgs);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerStoppedHandlerDelegate(Func<EventArgs, Task> handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public Task HandleServerStoppedAsync(EventArgs eventArgs)
{
return _handler(eventArgs);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerSubscriptionInterceptorDelegate : IMqttServerSubscriptionInterceptor
{
readonly Func<MqttSubscriptionInterceptorContext, Task> _callback;
public MqttServerSubscriptionInterceptorDelegate(Action<MqttSubscriptionInterceptorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerSubscriptionInterceptorDelegate(Func<MqttSubscriptionInterceptorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task InterceptSubscriptionAsync(MqttSubscriptionInterceptorContext context)
{
return _callback(context);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Threading.Tasks;
using MQTTnet.Implementations;
namespace MQTTnet.Server
{
public sealed class MqttServerUnsubscriptionInterceptorDelegate : IMqttServerUnsubscriptionInterceptor
{
readonly Func<MqttUnsubscriptionInterceptorContext, Task> _callback;
public MqttServerUnsubscriptionInterceptorDelegate(Action<MqttUnsubscriptionInterceptorContext> callback)
{
if (callback == null) throw new ArgumentNullException(nameof(callback));
_callback = context =>
{
callback(context);
return PlatformAbstractionLayer.CompletedTask;
};
}
public MqttServerUnsubscriptionInterceptorDelegate(Func<MqttUnsubscriptionInterceptorContext, Task> callback)
{
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
}
public Task InterceptUnsubscriptionAsync(MqttUnsubscriptionInterceptorContext context)
{
return _callback(context);
}
}
}
@@ -3,18 +3,12 @@ using MQTTnet.Server.Internal;
namespace MQTTnet.Server
{
public sealed class MqttServerOptions : IMqttServerOptions
public class MqttServerOptions
{
public MqttServerTcpEndpointOptions DefaultEndpointOptions { get; } = new MqttServerTcpEndpointOptions();
public MqttServerTlsTcpEndpointOptions TlsEndpointOptions { get; } = new MqttServerTlsTcpEndpointOptions();
/// <summary>
/// Gets or sets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; set; }
public bool EnablePersistentSessions { get; set; }
public int MaxPendingMessagesPerClient { get; set; } = 250;
@@ -24,19 +18,7 @@ namespace MQTTnet.Server
public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(15);
public TimeSpan KeepAliveMonitorInterval { get; set; } = TimeSpan.FromMilliseconds(500);
public IMqttServerConnectionValidator ConnectionValidator { get; set; }
public IMqttServerApplicationMessageInterceptor ApplicationMessageInterceptor { get; set; }
public IMqttServerClientMessageQueueInterceptor ClientMessageQueueInterceptor { get; set; }
public IMqttServerSubscriptionInterceptor SubscriptionInterceptor { get; set; }
public IMqttServerUnsubscriptionInterceptor UnsubscriptionInterceptor { get; set; }
public IMqttServerApplicationMessageInterceptor UndeliveredMessageInterceptor { get; set; }
public IMqttServerStorage Storage { get; set; }
public IMqttRetainedMessagesManager RetainedMessagesManager { get; set; } = new MqttRetainedMessagesManager();
@@ -152,97 +152,37 @@ namespace MQTTnet.Server
_options.RetainedMessagesManager = value;
return this;
}
public MqttServerOptionsBuilder WithConnectionValidator(IMqttServerConnectionValidator value)
{
_options.ConnectionValidator = value;
return this;
}
public MqttServerOptionsBuilder WithConnectionValidator(Action<MqttConnectionValidatorContext> value)
{
_options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithConnectionValidator(Func<MqttConnectionValidatorContext, Task> value)
{
_options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(value);
return this;
}
// public MqttServerOptionsBuilder WithApplicationMessageInterceptor(IMqttServerApplicationMessageInterceptor value)
// {
// _options.ApplicationMessageInterceptor = value;
// return this;
// }
//
// public MqttServerOptionsBuilder WithApplicationMessageInterceptor(Action<InterceptingMqttClientPublishEventArgs> value)
// {
// _options.ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
// return this;
// }
//
// public MqttServerOptionsBuilder WithApplicationMessageInterceptor(Func<InterceptingMqttClientPublishEventArgs, Task> value)
// {
// _options.ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
// return this;
// }
// public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Action<InterceptingMqttClientPublishEventArgs> value)
// {
// _options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
// return this;
// }
//
// public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Func<InterceptingMqttClientPublishEventArgs, Task> value)
// {
// _options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
// return this;
// }
public MqttServerOptionsBuilder WithApplicationMessageInterceptor(IMqttServerApplicationMessageInterceptor value)
{
_options.ApplicationMessageInterceptor = value;
return this;
}
public MqttServerOptionsBuilder WithApplicationMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
{
_options.ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithApplicationMessageInterceptor(Func<MqttApplicationMessageInterceptorContext, Task> value)
{
_options.ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
{
_options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Func<MqttApplicationMessageInterceptorContext, Task> value)
{
_options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithClientMessageQueueInterceptor(IMqttServerClientMessageQueueInterceptor value)
{
_options.ClientMessageQueueInterceptor = value;
return this;
}
public MqttServerOptionsBuilder WithClientMessageQueueInterceptor(Action<MqttClientMessageQueueInterceptorContext> value)
{
_options.ClientMessageQueueInterceptor = new MqttClientMessageQueueInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithSubscriptionInterceptor(IMqttServerSubscriptionInterceptor value)
{
_options.SubscriptionInterceptor = value;
return this;
}
public MqttServerOptionsBuilder WithSubscriptionInterceptor(Action<MqttSubscriptionInterceptorContext> value)
{
_options.SubscriptionInterceptor = new MqttServerSubscriptionInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithUnsubscriptionInterceptor(IMqttServerUnsubscriptionInterceptor value)
{
_options.UnsubscriptionInterceptor = value;
return this;
}
public MqttServerOptionsBuilder WithUnsubscriptionInterceptor(Action<MqttUnsubscriptionInterceptorContext> value)
{
_options.UnsubscriptionInterceptor = new MqttServerUnsubscriptionInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithUndeliveredMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
{
_options.UndeliveredMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
return this;
}
public MqttServerOptionsBuilder WithDefaultEndpointReuseAddress()
{
_options.DefaultEndpointOptions.ReuseAddress = true;
@@ -261,16 +201,16 @@ namespace MQTTnet.Server
return this;
}
/// <summary>
/// Gets or sets the client ID which is used when publishing messages from the server directly.
/// </summary>
public MqttServerOptionsBuilder WithClientId(string value)
{
_options.ClientId = value;
return this;
}
// /// <summary>
// /// Gets or sets the client ID which is used when publishing messages from the server directly.
// /// </summary>
// public MqttServerOptionsBuilder WithClientId(string value)
// {
// _options.ClientId = value;
// return this;
// }
public IMqttServerOptions Build()
public MqttServerOptions Build()
{
return _options;
}
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using MQTTnet.Packets;
using MQTTnet.Server.Internal;
namespace MQTTnet.Server
{
public sealed class PreparingMqttClientSessionEventArgs : EventArgs
{
public string ClientId { get; internal set; }
// TODO: Allow adding of packets to the queue etc.
/*
* The Session State in the Server consists of:
· The existence of a Session, even if the rest of the Session State is empty.
· The Clients subscriptions, including any Subscription Identifiers.
· QoS 1 and QoS 2 messages which have been sent to the Client, but have not been completely acknowledged.
· QoS 1 and QoS 2 messages pending transmission to the Client and OPTIONALLY QoS 0 messages pending transmission to the Client.
· QoS 2 messages which have been received from the Client, but have not been completely acknowledged.The Will Message and the Will Delay Interval
· If the Session is currently not connected, the time at which the Session will end and Session State will be discarded.
*/
public bool IsExistingSession { get; set; }
public List<MqttSubscription> Subscriptions { get; } = new List<MqttSubscription>();
public List<MqttPublishPacket> PublishPackets { get; } = new List<MqttPublishPacket>();
}
}
@@ -1,8 +1,8 @@
using MQTTnet.Formatter;
using System;
using System;
using System.Threading.Tasks;
using MQTTnet.Formatter;
namespace MQTTnet.Server.Status
namespace MQTTnet.Server
{
public interface IMqttClientStatus
{
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MQTTnet.Server.Status
namespace MQTTnet.Server
{
public interface IMqttSessionStatus
{
@@ -1,10 +1,10 @@
using MQTTnet.Formatter;
using System;
using System;
using System.Threading.Tasks;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Formatter;
using MQTTnet.Server.Internal;
namespace MQTTnet.Server.Status
namespace MQTTnet.Server
{
public sealed class MqttClientStatus : IMqttClientStatus
{
@@ -2,12 +2,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using MQTTnet.Formatter;
using MQTTnet.Formatter.V5;
using MQTTnet.Implementations;
using MQTTnet.Internal;
using MQTTnet.Server.Internal;
namespace MQTTnet.Server.Status
namespace MQTTnet.Server
{
public sealed class MqttSessionStatus : IMqttSessionStatus
{
@@ -10,12 +10,12 @@ using MQTTnet.Protocol;
namespace MQTTnet.Server
{
public sealed class MqttConnectionValidatorContext
public sealed class ValidatingMqttClientConnectionEventArgs : EventArgs
{
readonly MqttConnectPacket _connectPacket;
readonly IMqttChannelAdapter _clientAdapter;
public MqttConnectionValidatorContext(MqttConnectPacket connectPacket, IMqttChannelAdapter clientAdapter)
public ValidatingMqttClientConnectionEventArgs(MqttConnectPacket connectPacket, IMqttChannelAdapter clientAdapter)
{
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
_clientAdapter = clientAdapter ?? throw new ArgumentNullException(nameof(clientAdapter));