mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-20 11:45:43 +08:00
Removed 3rd-Party libraries.
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Packets;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
public interface IMqttClientRetainedMessageManager
|
||||
{
|
||||
Task LoadMessagesAsync();
|
||||
|
||||
Task HandleMessageAsync(string clientId, MqttApplicationMessage applicationMessage);
|
||||
|
||||
Task<List<MqttApplicationMessage>> GetSubscribedMessagesAsync(MqttSubscribePacket subscribePacket);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
public interface IMqttClientSesssionFactory
|
||||
{
|
||||
MqttClientSession CreateClientSession(string sessionId, MqttClientSessionsManager mqttClientSessionsManager);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace MQTTnet.Core.Server
|
||||
|
||||
Task<IList<ConnectedMqttClient>> GetConnectedClientsAsync();
|
||||
|
||||
Task StartAsync();
|
||||
Task StartAsync(MqttServerOptions options);
|
||||
Task StopAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MQTTnet.Core.Adapter;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
@@ -6,6 +8,6 @@ namespace MQTTnet.Core.Server
|
||||
{
|
||||
IMqttServer CreateMqttServer();
|
||||
|
||||
IMqttServer CreateMqttServer(Action<MqttServerOptions> configure);
|
||||
IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Adapter;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
using MQTTnet.Core.Exceptions;
|
||||
using MQTTnet.Core.Packets;
|
||||
using MQTTnet.Core.Protocol;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
@@ -15,16 +15,16 @@ namespace MQTTnet.Core.Server
|
||||
private readonly BlockingCollection<MqttPublishPacket> _pendingPublishPackets = new BlockingCollection<MqttPublishPacket>();
|
||||
private readonly MqttServerOptions _options;
|
||||
private readonly MqttClientSession _session;
|
||||
private readonly ILogger<MqttClientPendingMessagesQueue> _logger;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
|
||||
public MqttClientPendingMessagesQueue(MqttServerOptions options, MqttClientSession session, ILogger<MqttClientPendingMessagesQueue> logger)
|
||||
public MqttClientPendingMessagesQueue(MqttServerOptions options, MqttClientSession session, IMqttNetLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_session = session ?? throw new ArgumentNullException(nameof(session));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
public void Start(IMqttCommunicationAdapter adapter, CancellationToken cancellationToken)
|
||||
public void Start(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||
{
|
||||
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace MQTTnet.Core.Server
|
||||
if (publishPacket == null) throw new ArgumentNullException(nameof(publishPacket));
|
||||
|
||||
_pendingPublishPackets.Add(publishPacket);
|
||||
_logger.LogTrace("Enqueued packet (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Trace<MqttClientPendingMessagesQueue>("Enqueued packet (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
|
||||
private async Task SendPendingPublishPacketsAsync(IMqttCommunicationAdapter adapter, CancellationToken cancellationToken)
|
||||
private async Task SendPendingPublishPacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -58,11 +58,11 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Unhandled exception while sending enqueued packet (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Error<MqttClientPendingMessagesQueue>(exception, "Unhandled exception while sending enqueued packet (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendPendingPublishPacketAsync(IMqttCommunicationAdapter adapter, CancellationToken cancellationToken)
|
||||
private async Task SendPendingPublishPacketAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||
{
|
||||
MqttPublishPacket packet = null;
|
||||
try
|
||||
@@ -70,24 +70,24 @@ namespace MQTTnet.Core.Server
|
||||
packet = _pendingPublishPackets.Take(cancellationToken);
|
||||
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, packet).ConfigureAwait(false);
|
||||
|
||||
_logger.LogTrace("Enqueued packet sent (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Trace<MqttClientPendingMessagesQueue>("Enqueued packet sent (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is MqttCommunicationTimedOutException)
|
||||
{
|
||||
_logger.LogWarning(new EventId(), exception, "Sending publish packet failed due to timeout (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Warning<MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed due to timeout (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
else if (exception is MqttCommunicationException)
|
||||
{
|
||||
_logger.LogWarning(new EventId(), exception, "Sending publish packet failed due to communication exception (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Warning<MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed due to communication exception (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
else if (exception is OperationCanceledException)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Sending publish packet failed (ClientId: {0}).", _session.ClientId);
|
||||
_logger.Error<MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed (ClientId: {0}).", _session.ClientId);
|
||||
}
|
||||
|
||||
if (packet != null && packet.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
|
||||
|
||||
@@ -3,13 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Adapter;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
using MQTTnet.Core.Exceptions;
|
||||
using MQTTnet.Core.Internal;
|
||||
using MQTTnet.Core.Packets;
|
||||
using MQTTnet.Core.Protocol;
|
||||
using MQTTnet.Core.Serializer;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
@@ -21,28 +20,27 @@ namespace MQTTnet.Core.Server
|
||||
private readonly MqttClientSessionsManager _sessionsManager;
|
||||
private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue;
|
||||
private readonly MqttServerOptions _options;
|
||||
private readonly ILogger<MqttClientSession> _logger;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
|
||||
private IMqttCommunicationAdapter _adapter;
|
||||
private IMqttChannelAdapter _adapter;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private MqttApplicationMessage _willMessage;
|
||||
|
||||
public MqttClientSession(
|
||||
string clientId,
|
||||
IOptions<MqttServerOptions> options,
|
||||
MqttServerOptions options,
|
||||
MqttClientSessionsManager sessionsManager,
|
||||
MqttClientSubscriptionsManager subscriptionsManager,
|
||||
ILogger<MqttClientSession> logger,
|
||||
ILogger<MqttClientPendingMessagesQueue> messageQueueLogger)
|
||||
IMqttNetLogger logger)
|
||||
{
|
||||
_sessionsManager = sessionsManager ?? throw new ArgumentNullException(nameof(sessionsManager));
|
||||
_subscriptionsManager = subscriptionsManager ?? throw new ArgumentNullException(nameof(subscriptionsManager));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
ClientId = clientId;
|
||||
|
||||
_options = options.Value;
|
||||
_pendingMessagesQueue = new MqttClientPendingMessagesQueue(_options, this, messageQueueLogger);
|
||||
_options = options;
|
||||
|
||||
_subscriptionsManager = new MqttClientSubscriptionsManager(_options);
|
||||
_pendingMessagesQueue = new MqttClientPendingMessagesQueue(_options, this, _logger);
|
||||
}
|
||||
|
||||
public string ClientId { get; }
|
||||
@@ -51,7 +49,7 @@ namespace MQTTnet.Core.Server
|
||||
|
||||
public bool IsConnected => _adapter != null;
|
||||
|
||||
public async Task RunAsync(MqttApplicationMessage willMessage, IMqttCommunicationAdapter adapter)
|
||||
public async Task RunAsync(MqttApplicationMessage willMessage, IMqttChannelAdapter adapter)
|
||||
{
|
||||
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
|
||||
|
||||
@@ -71,11 +69,11 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (MqttCommunicationException exception)
|
||||
{
|
||||
_logger.LogWarning(new EventId(), exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
_logger.Warning<MqttClientSession>(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
_logger.Error<MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +91,7 @@ namespace MQTTnet.Core.Server
|
||||
_adapter = null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Client '{0}': Session stopped.", ClientId);
|
||||
_logger.Info<MqttClientSession>("Client '{0}': Session stopped.", ClientId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -120,7 +118,7 @@ namespace MQTTnet.Core.Server
|
||||
_pendingMessagesQueue.Enqueue(publishPacket);
|
||||
}
|
||||
|
||||
private async Task ReceivePacketsAsync(IMqttCommunicationAdapter adapter, CancellationToken cancellationToken)
|
||||
private async Task ReceivePacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -135,17 +133,17 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (MqttCommunicationException exception)
|
||||
{
|
||||
_logger.LogWarning(new EventId(), exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
_logger.Warning<MqttClientSession>(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
await StopAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
_logger.Error<MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
await StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private Task ProcessReceivedPacketAsync(IMqttCommunicationAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
|
||||
private Task ProcessReceivedPacketAsync(IMqttChannelAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
|
||||
{
|
||||
if (packet is MqttPingReqPacket)
|
||||
{
|
||||
@@ -188,11 +186,11 @@ namespace MQTTnet.Core.Server
|
||||
return StopAsync();
|
||||
}
|
||||
|
||||
_logger.LogWarning("Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
||||
_logger.Warning<MqttClientSession>("Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
||||
return StopAsync();
|
||||
}
|
||||
|
||||
private async Task HandleIncomingSubscribePacketAsync(IMqttCommunicationAdapter adapter, MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
|
||||
private async Task HandleIncomingSubscribePacketAsync(IMqttChannelAdapter adapter, MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
|
||||
{
|
||||
var subscribeResult = _subscriptionsManager.Subscribe(subscribePacket, ClientId);
|
||||
|
||||
@@ -215,7 +213,7 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleIncomingPublishPacketAsync(IMqttCommunicationAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||
private async Task HandleIncomingPublishPacketAsync(IMqttChannelAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||
{
|
||||
var applicationMessage = publishPacket.ToApplicationMessage();
|
||||
|
||||
@@ -255,7 +253,7 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
}
|
||||
|
||||
private Task HandleIncomingPubRelPacketAsync(IMqttCommunicationAdapter adapter, MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
||||
private Task HandleIncomingPubRelPacketAsync(IMqttChannelAdapter adapter, MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
||||
{
|
||||
lock (_unacknowledgedPublishPackets)
|
||||
{
|
||||
|
||||
@@ -4,13 +4,12 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Adapter;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
using MQTTnet.Core.Exceptions;
|
||||
using MQTTnet.Core.Internal;
|
||||
using MQTTnet.Core.Packets;
|
||||
using MQTTnet.Core.Protocol;
|
||||
using MQTTnet.Core.Serializer;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
@@ -20,27 +19,21 @@ namespace MQTTnet.Core.Server
|
||||
private readonly SemaphoreSlim _sessionsSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
private readonly MqttServerOptions _options;
|
||||
private readonly ILogger<MqttClientSessionsManager> _logger;
|
||||
private readonly IMqttClientSesssionFactory _clientSesssionFactory;
|
||||
private readonly IMqttClientRetainedMessageManager _clientRetainedMessageManager;
|
||||
private readonly MqttRetainedMessagesManager _retainedMessagesManager;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
|
||||
public MqttClientSessionsManager(
|
||||
IOptions<MqttServerOptions> options,
|
||||
ILogger<MqttClientSessionsManager> logger,
|
||||
IMqttClientSesssionFactory clientSesssionFactory,
|
||||
IMqttClientRetainedMessageManager clientRetainedMessageManager)
|
||||
public MqttClientSessionsManager(MqttServerOptions options, MqttRetainedMessagesManager retainedMessagesManager, IMqttNetLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
|
||||
_clientSesssionFactory = clientSesssionFactory ?? throw new ArgumentNullException(nameof(clientSesssionFactory));
|
||||
_clientRetainedMessageManager = clientRetainedMessageManager ?? throw new ArgumentNullException(nameof(clientRetainedMessageManager));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
|
||||
}
|
||||
|
||||
public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
|
||||
public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
|
||||
public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
|
||||
|
||||
public async Task RunClientSessionAsync(IMqttCommunicationAdapter clientAdapter, CancellationToken cancellationToken)
|
||||
public async Task RunClientSessionAsync(IMqttChannelAdapter clientAdapter, CancellationToken cancellationToken)
|
||||
{
|
||||
var clientId = string.Empty;
|
||||
try
|
||||
@@ -80,14 +73,11 @@ namespace MQTTnet.Core.Server
|
||||
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
|
||||
}));
|
||||
|
||||
using (_logger.BeginScope(clientId))
|
||||
{
|
||||
await clientSession.Session.RunAsync(connectPacket.WillMessage, clientAdapter).ConfigureAwait(false);
|
||||
}
|
||||
await clientSession.Session.RunAsync(connectPacket.WillMessage, clientAdapter).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, exception.Message);
|
||||
_logger.Error<MqttClientSessionsManager>(exception, exception.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -157,7 +147,7 @@ namespace MQTTnet.Core.Server
|
||||
|
||||
if (applicationMessage.Retain)
|
||||
{
|
||||
await _clientRetainedMessageManager.HandleMessageAsync(senderClientSession?.ClientId, applicationMessage).ConfigureAwait(false);
|
||||
await _retainedMessagesManager.HandleMessageAsync(senderClientSession?.ClientId, applicationMessage).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var eventArgs = new MqttApplicationMessageReceivedEventArgs(senderClientSession?.ClientId, applicationMessage);
|
||||
@@ -165,7 +155,7 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Error while processing application message");
|
||||
_logger.Error<MqttClientSessionsManager>(exception, "Error while processing application message");
|
||||
}
|
||||
|
||||
lock (_sessions)
|
||||
@@ -179,7 +169,7 @@ namespace MQTTnet.Core.Server
|
||||
|
||||
public Task<List<MqttApplicationMessage>> GetRetainedMessagesAsync(MqttSubscribePacket subscribePacket)
|
||||
{
|
||||
return _clientRetainedMessageManager.GetSubscribedMessagesAsync(subscribePacket);
|
||||
return _retainedMessagesManager.GetSubscribedMessagesAsync(subscribePacket);
|
||||
}
|
||||
|
||||
private MqttConnectReturnCode ValidateConnection(MqttConnectPacket connectPacket)
|
||||
@@ -206,11 +196,11 @@ namespace MQTTnet.Core.Server
|
||||
await clientSession.StopAsync();
|
||||
clientSession = null;
|
||||
|
||||
_logger.LogTrace("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Trace<MqttClientSessionsManager>("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogTrace("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Trace<MqttClientSessionsManager>("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,10 +209,10 @@ namespace MQTTnet.Core.Server
|
||||
{
|
||||
isExistingSession = false;
|
||||
|
||||
clientSession = _clientSesssionFactory.CreateClientSession(connectPacket.ClientId, this);
|
||||
clientSession = new MqttClientSession(connectPacket.ClientId, _options, this, _logger);
|
||||
_sessions[connectPacket.ClientId] = clientSession;
|
||||
|
||||
_logger.LogTrace("Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Trace<MqttClientSessionsManager>("Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
|
||||
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MQTTnet.Core.Packets;
|
||||
using MQTTnet.Core.Protocol;
|
||||
|
||||
@@ -11,9 +10,9 @@ namespace MQTTnet.Core.Server
|
||||
private readonly Dictionary<string, MqttQualityOfServiceLevel> _subscriptions = new Dictionary<string, MqttQualityOfServiceLevel>();
|
||||
private readonly MqttServerOptions _options;
|
||||
|
||||
public MqttClientSubscriptionsManager(IOptions<MqttServerOptions> options)
|
||||
public MqttClientSubscriptionsManager(MqttServerOptions options)
|
||||
{
|
||||
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
public MqttClientSubscribeResult Subscribe(MqttSubscribePacket subscribePacket, string clientId)
|
||||
|
||||
+10
-11
@@ -4,22 +4,21 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Packets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
public sealed class MqttClientRetainedMessagesManager : IMqttClientRetainedMessageManager
|
||||
public sealed class MqttRetainedMessagesManager
|
||||
{
|
||||
private readonly Dictionary<string, MqttApplicationMessage> _retainedMessages = new Dictionary<string, MqttApplicationMessage>();
|
||||
private readonly SemaphoreSlim _gate = new SemaphoreSlim(1, 1);
|
||||
private readonly ILogger<MqttClientRetainedMessagesManager> _logger;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly MqttServerOptions _options;
|
||||
|
||||
public MqttClientRetainedMessagesManager(IOptions<MqttServerOptions> options, ILogger<MqttClientRetainedMessagesManager> logger)
|
||||
public MqttRetainedMessagesManager(MqttServerOptions options, IMqttNetLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
public async Task LoadMessagesAsync()
|
||||
@@ -42,7 +41,7 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Unhandled exception while loading retained messages.");
|
||||
_logger.Error<MqttRetainedMessagesManager>(exception, "Unhandled exception while loading retained messages.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -61,7 +60,7 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(new EventId(), exception, "Unhandled exception while handling retained messages.");
|
||||
_logger.Error<MqttRetainedMessagesManager>(exception, "Unhandled exception while handling retained messages.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -110,7 +109,7 @@ namespace MQTTnet.Core.Server
|
||||
if (applicationMessage.Payload?.Any() == false)
|
||||
{
|
||||
saveIsRequired = _retainedMessages.Remove(applicationMessage.Topic);
|
||||
_logger.LogInformation("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
_logger.Info<MqttRetainedMessagesManager>("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -129,12 +128,12 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
_logger.Info<MqttRetainedMessagesManager>("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
|
||||
if (!saveIsRequired)
|
||||
{
|
||||
_logger.LogTrace("Skipped saving retained messages because no changes were detected.");
|
||||
_logger.Trace<MqttRetainedMessagesManager>("Skipped saving retained messages because no changes were detected.");
|
||||
}
|
||||
|
||||
if (saveIsRequired && _options.Storage != null)
|
||||
@@ -3,33 +3,24 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Core.Adapter;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Linq;
|
||||
using MQTTnet.Core.Diagnostics;
|
||||
|
||||
namespace MQTTnet.Core.Server
|
||||
{
|
||||
public class MqttServer : IMqttServer
|
||||
{
|
||||
private readonly IMqttClientRetainedMessageManager _clientRetainedMessageManager;
|
||||
private readonly ILogger<MqttServer> _logger;
|
||||
private readonly MqttClientSessionsManager _clientSessionsManager;
|
||||
private readonly ICollection<IMqttServerAdapter> _adapters;
|
||||
private readonly MqttServerOptions _options;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
|
||||
private MqttClientSessionsManager _clientSessionsManager;
|
||||
private MqttRetainedMessagesManager _retainedMessagesManager;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private MqttServerOptions _options;
|
||||
|
||||
public MqttServer(
|
||||
IOptions<MqttServerOptions> options,
|
||||
IEnumerable<IMqttServerAdapter> adapters,
|
||||
ILogger<MqttServer> logger,
|
||||
MqttClientSessionsManager clientSessionsManager,
|
||||
IMqttClientRetainedMessageManager clientRetainedMessageManager)
|
||||
public MqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
|
||||
{
|
||||
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_clientSessionsManager = clientSessionsManager ?? throw new ArgumentNullException(nameof(clientSessionsManager));
|
||||
_clientRetainedMessageManager = clientRetainedMessageManager ?? throw new ArgumentNullException(nameof(clientRetainedMessageManager));
|
||||
|
||||
if (adapters == null)
|
||||
{
|
||||
@@ -37,15 +28,6 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
|
||||
_adapters = adapters.ToList();
|
||||
|
||||
_clientSessionsManager.ApplicationMessageReceived += (s, e) => ApplicationMessageReceived?.Invoke(s, e);
|
||||
_clientSessionsManager.ClientConnected += OnClientConnected;
|
||||
_clientSessionsManager.ClientDisconnected += OnClientDisconnected;
|
||||
}
|
||||
|
||||
public Task<IList<ConnectedMqttClient>> GetConnectedClientsAsync()
|
||||
{
|
||||
return _clientSessionsManager.GetConnectedClientsAsync();
|
||||
}
|
||||
|
||||
public event EventHandler<MqttServerStartedEventArgs> Started;
|
||||
@@ -53,14 +35,16 @@ namespace MQTTnet.Core.Server
|
||||
public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
|
||||
public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
|
||||
|
||||
public Task<IList<ConnectedMqttClient>> GetConnectedClientsAsync()
|
||||
{
|
||||
return _clientSessionsManager.GetConnectedClientsAsync();
|
||||
}
|
||||
|
||||
public async Task PublishAsync(IEnumerable<MqttApplicationMessage> applicationMessages)
|
||||
{
|
||||
if (applicationMessages == null) throw new ArgumentNullException(nameof(applicationMessages));
|
||||
|
||||
if (_cancellationTokenSource == null)
|
||||
{
|
||||
throw new InvalidOperationException("The server is not started.");
|
||||
}
|
||||
if (_cancellationTokenSource == null) throw new InvalidOperationException("The server is not started.");
|
||||
|
||||
foreach (var applicationMessage in applicationMessages)
|
||||
{
|
||||
@@ -68,13 +52,21 @@ namespace MQTTnet.Core.Server
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StartAsync()
|
||||
public async Task StartAsync(MqttServerOptions options)
|
||||
{
|
||||
if (_cancellationTokenSource != null) throw new InvalidOperationException("The MQTT server is already started.");
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (_cancellationTokenSource != null) throw new InvalidOperationException("The server is already started.");
|
||||
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_retainedMessagesManager = new MqttRetainedMessagesManager(_options, _logger);
|
||||
|
||||
await _clientRetainedMessageManager.LoadMessagesAsync();
|
||||
_clientSessionsManager = new MqttClientSessionsManager(_options, _retainedMessagesManager, _logger);
|
||||
_clientSessionsManager.ApplicationMessageReceived += OnApplicationMessageReceived;
|
||||
_clientSessionsManager.ClientConnected += OnClientConnected;
|
||||
_clientSessionsManager.ClientDisconnected += OnClientDisconnected;
|
||||
|
||||
await _retainedMessagesManager.LoadMessagesAsync();
|
||||
|
||||
foreach (var adapter in _adapters)
|
||||
{
|
||||
@@ -82,26 +74,48 @@ namespace MQTTnet.Core.Server
|
||||
await adapter.StartAsync(_options);
|
||||
}
|
||||
|
||||
_logger.LogInformation("Started.");
|
||||
_logger.Info<MqttServer>("Started.");
|
||||
|
||||
Started?.Invoke(this, new MqttServerStartedEventArgs());
|
||||
}
|
||||
|
||||
public async Task StopAsync()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel(false);
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
|
||||
foreach (var adapter in _adapters)
|
||||
try
|
||||
{
|
||||
adapter.ClientAccepted -= OnClientAccepted;
|
||||
await adapter.StopAsync();
|
||||
if (_cancellationTokenSource == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cancellationTokenSource.Cancel(false);
|
||||
_cancellationTokenSource.Dispose();
|
||||
|
||||
foreach (var adapter in _adapters)
|
||||
{
|
||||
adapter.ClientAccepted -= OnClientAccepted;
|
||||
await adapter.StopAsync();
|
||||
}
|
||||
|
||||
await _clientSessionsManager.StopAsync();
|
||||
|
||||
_logger.Info<MqttServer>("Stopped.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cancellationTokenSource = null;
|
||||
|
||||
await _clientSessionsManager.StopAsync();
|
||||
_retainedMessagesManager = null;
|
||||
|
||||
_logger.LogInformation("Stopped.");
|
||||
if (_clientSessionsManager != null)
|
||||
{
|
||||
_clientSessionsManager.ApplicationMessageReceived -= OnApplicationMessageReceived;
|
||||
_clientSessionsManager.ClientConnected -= OnClientConnected;
|
||||
_clientSessionsManager.ClientDisconnected -= OnClientDisconnected;
|
||||
}
|
||||
|
||||
_clientSessionsManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
|
||||
@@ -111,14 +125,19 @@ namespace MQTTnet.Core.Server
|
||||
|
||||
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
|
||||
{
|
||||
_logger.LogInformation("Client '{0}': Connected.", eventArgs.Client.ClientId);
|
||||
_logger.Info<MqttServer>("Client '{0}': Connected.", eventArgs.Client.ClientId);
|
||||
ClientConnected?.Invoke(this, eventArgs);
|
||||
}
|
||||
|
||||
private void OnClientDisconnected(object sender, MqttClientDisconnectedEventArgs eventArgs)
|
||||
{
|
||||
_logger.LogInformation("Client '{0}': Disconnected.", eventArgs.Client.ClientId);
|
||||
_logger.Info<MqttServer>("Client '{0}': Disconnected.", eventArgs.Client.ClientId);
|
||||
ClientDisconnected?.Invoke(this, eventArgs);
|
||||
}
|
||||
|
||||
private void OnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
|
||||
{
|
||||
ApplicationMessageReceived?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user