mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-16 17:23:04 +08:00
Refactor logging and add benchmark.
This commit is contained in:
@@ -13,7 +13,7 @@ namespace MQTTnet.AspNetCore
|
||||
{
|
||||
private readonly IMqttServerOptions _options;
|
||||
|
||||
public MqttHostedServer(IMqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger) : base(adapters, logger)
|
||||
public MqttHostedServer(IMqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger) : base(adapters, logger.CreateChildLogger(nameof(MqttHostedServer)))
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace MQTTnet.AspNetCore
|
||||
{
|
||||
if (webSocket == null) throw new ArgumentNullException(nameof(webSocket));
|
||||
|
||||
var clientAdapter = new MqttChannelAdapter(new MqttWebSocketChannel(webSocket), new MqttPacketSerializer(), new MqttNetLogger());
|
||||
var clientAdapter = new MqttChannelAdapter(new MqttWebSocketChannel(webSocket), new MqttPacketSerializer(), new MqttNetLogger().CreateChildLogger(nameof(MqttWebSocketServerAdapter)));
|
||||
|
||||
var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);
|
||||
ClientAccepted?.Invoke(this, eventArgs);
|
||||
|
||||
@@ -18,16 +18,19 @@ namespace MQTTnet.Adapter
|
||||
private const uint ErrorOperationAborted = 0x800703E3;
|
||||
private const int ReadBufferSize = 4096; // TODO: Move buffer size to config
|
||||
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
private readonly IMqttChannel _channel;
|
||||
|
||||
private bool _isDisposed;
|
||||
|
||||
public MqttChannelAdapter(IMqttChannel channel, IMqttPacketSerializer serializer, IMqttNetLogger logger)
|
||||
public MqttChannelAdapter(IMqttChannel channel, IMqttPacketSerializer serializer, IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||
PacketSerializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttChannelAdapter));
|
||||
}
|
||||
|
||||
public IMqttPacketSerializer PacketSerializer { get; }
|
||||
@@ -35,7 +38,7 @@ namespace MQTTnet.Adapter
|
||||
public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
_logger.Verbose<MqttChannelAdapter>("Connecting [Timeout={0}]", timeout);
|
||||
_logger.Verbose("Connecting [Timeout={0}]", timeout);
|
||||
|
||||
return ExecuteAndWrapExceptionAsync(() =>
|
||||
Internal.TaskExtensions.TimeoutAfter(ct => _channel.ConnectAsync(ct), timeout, cancellationToken));
|
||||
@@ -44,7 +47,7 @@ namespace MQTTnet.Adapter
|
||||
public Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
_logger.Verbose<MqttChannelAdapter>("Disconnecting [Timeout={0}]", timeout);
|
||||
_logger.Verbose("Disconnecting [Timeout={0}]", timeout);
|
||||
|
||||
return ExecuteAndWrapExceptionAsync(() =>
|
||||
Internal.TaskExtensions.TimeoutAfter(ct => _channel.DisconnectAsync(), timeout, cancellationToken));
|
||||
@@ -69,7 +72,7 @@ namespace MQTTnet.Adapter
|
||||
{
|
||||
return ExecuteAndWrapExceptionAsync(() =>
|
||||
{
|
||||
_logger.Verbose<MqttChannelAdapter>("TX >>> {0} [Timeout={1}]", packet, timeout);
|
||||
_logger.Verbose("TX >>> {0} [Timeout={1}]", packet, timeout);
|
||||
|
||||
var packetData = PacketSerializer.Serialize(packet);
|
||||
|
||||
@@ -111,7 +114,7 @@ namespace MQTTnet.Adapter
|
||||
throw new MqttProtocolViolationException("Received malformed packet.");
|
||||
}
|
||||
|
||||
_logger.Verbose<MqttChannelAdapter>("RX <<< {0}", packet);
|
||||
_logger.Verbose("RX <<< {0}", packet);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -5,6 +5,6 @@ namespace MQTTnet.Client
|
||||
{
|
||||
public interface IMqttClientAdapterFactory
|
||||
{
|
||||
IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger);
|
||||
IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace MQTTnet.Client
|
||||
private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
|
||||
|
||||
private readonly IMqttClientAdapterFactory _adapterFactory;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private IMqttClientOptions _options;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
@@ -31,8 +31,10 @@ namespace MQTTnet.Client
|
||||
|
||||
public MqttClient(IMqttClientAdapterFactory channelFactory, IMqttNetLogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_adapterFactory = channelFactory ?? throw new ArgumentNullException(nameof(channelFactory));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_logger = logger.CreateChildLogger(nameof(MqttClient));
|
||||
}
|
||||
|
||||
public event EventHandler<MqttClientConnectedEventArgs> Connected;
|
||||
@@ -57,14 +59,14 @@ namespace MQTTnet.Client
|
||||
|
||||
_adapter = _adapterFactory.CreateClientAdapter(options, _logger);
|
||||
|
||||
_logger.Verbose(this, "Trying to connect with server.");
|
||||
_logger.Verbose("Trying to connect with server.");
|
||||
await _adapter.ConnectAsync(_options.CommunicationTimeout, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
_logger.Verbose(this, "Connection with server established.");
|
||||
_logger.Verbose("Connection with server established.");
|
||||
|
||||
StartReceivingPackets(_cancellationTokenSource.Token);
|
||||
|
||||
var connectResponse = await AuthenticateAsync(options.WillMessage, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
_logger.Verbose(this, "MQTT connection with server established.");
|
||||
_logger.Verbose("MQTT connection with server established.");
|
||||
|
||||
_sendTracker.Restart();
|
||||
|
||||
@@ -76,12 +78,12 @@ namespace MQTTnet.Client
|
||||
IsConnected = true;
|
||||
Connected?.Invoke(this, new MqttClientConnectedEventArgs(connectResponse.IsSessionPresent));
|
||||
|
||||
_logger.Info(this, "Connected.");
|
||||
_logger.Info("Connected.");
|
||||
return new MqttClientConnectResult(connectResponse.IsSessionPresent);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(this, exception, "Error while connecting with server.");
|
||||
_logger.Error(exception, "Error while connecting with server.");
|
||||
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
|
||||
|
||||
throw;
|
||||
@@ -245,7 +247,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
catch (Exception adapterException)
|
||||
{
|
||||
_logger.Warning(this, adapterException, "Error while disconnecting from adapter.");
|
||||
_logger.Warning(adapterException, "Error while disconnecting from adapter.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -265,11 +267,11 @@ namespace MQTTnet.Client
|
||||
await _adapter.DisconnectAsync(_options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.Verbose(this, "Disconnected from adapter.");
|
||||
_logger.Verbose("Disconnected from adapter.");
|
||||
}
|
||||
catch (Exception adapterException)
|
||||
{
|
||||
_logger.Warning(this, adapterException, "Error while disconnecting from adapter.");
|
||||
_logger.Warning(adapterException, "Error while disconnecting from adapter.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -278,7 +280,7 @@ namespace MQTTnet.Client
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
|
||||
_logger.Info(this, "Disconnected.");
|
||||
_logger.Info("Disconnected.");
|
||||
Disconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(clientWasConnected, exception));
|
||||
}
|
||||
}
|
||||
@@ -324,7 +326,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
catch (MqttCommunicationTimedOutException)
|
||||
{
|
||||
_logger.Warning(this, null, "Timeout while waiting for packet of type '{0}'.", typeof(TResponsePacket).Namespace);
|
||||
_logger.Warning(null, "Timeout while waiting for packet of type '{0}'.", typeof(TResponsePacket).Namespace);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
@@ -335,7 +337,7 @@ namespace MQTTnet.Client
|
||||
|
||||
private async Task SendKeepAliveMessagesAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Verbose(this, "Start sending keep alive packets.");
|
||||
_logger.Verbose("Start sending keep alive packets.");
|
||||
|
||||
try
|
||||
{
|
||||
@@ -362,24 +364,24 @@ namespace MQTTnet.Client
|
||||
}
|
||||
else if (exception is MqttCommunicationException)
|
||||
{
|
||||
_logger.Warning(this, exception, "MQTT communication exception while sending/receiving keep alive packets.");
|
||||
_logger.Warning(exception, "MQTT communication exception while sending/receiving keep alive packets.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error(this, exception, "Unhandled exception while sending/receiving keep alive packets.");
|
||||
_logger.Error(exception, "Unhandled exception while sending/receiving keep alive packets.");
|
||||
}
|
||||
|
||||
await DisconnectInternalAsync(_keepAliveMessageSenderTask, exception).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.Verbose(this, "Stopped sending keep alive packets.");
|
||||
_logger.Verbose("Stopped sending keep alive packets.");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReceivePacketsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.Verbose(this, "Start receiving packets.");
|
||||
_logger.Verbose("Start receiving packets.");
|
||||
|
||||
try
|
||||
{
|
||||
@@ -414,11 +416,11 @@ namespace MQTTnet.Client
|
||||
}
|
||||
else if (exception is MqttCommunicationException)
|
||||
{
|
||||
_logger.Warning(this, exception, "MQTT communication exception while receiving packets.");
|
||||
_logger.Warning(exception, "MQTT communication exception while receiving packets.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error(this, exception, "Unhandled exception while receiving packets.");
|
||||
_logger.Error(exception, "Unhandled exception while receiving packets.");
|
||||
}
|
||||
|
||||
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
|
||||
@@ -426,7 +428,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.Verbose(this, "Stopped receiving packets.");
|
||||
_logger.Verbose("Stopped receiving packets.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +464,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(this, exception, "Unhandled exception while processing received packet.");
|
||||
_logger.Error(exception, "Unhandled exception while processing received packet.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +536,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(this, exception, "Unhandled exception while handling application message.");
|
||||
_logger.Error(exception, "Unhandled exception while handling application message.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace MQTTnet.Diagnostics
|
||||
{
|
||||
public interface IMqttNetChildLogger
|
||||
{
|
||||
IMqttNetChildLogger CreateChildLogger(string source);
|
||||
|
||||
void Verbose(string message, params object[] parameters);
|
||||
|
||||
void Info(string message, params object[] parameters);
|
||||
|
||||
void Warning(Exception exception, string message, params object[] parameters);
|
||||
|
||||
void Error(Exception exception, string message, params object[] parameters);
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,8 @@ namespace MQTTnet.Diagnostics
|
||||
{
|
||||
event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
||||
|
||||
void Verbose<TSource>(string message, params object[] parameters);
|
||||
IMqttNetChildLogger CreateChildLogger(string source);
|
||||
|
||||
void Verbose(object source, string message, params object[] parameters);
|
||||
|
||||
void Info<TSource>(string message, params object[] parameters);
|
||||
|
||||
void Info(object source, string message, params object[] parameters);
|
||||
|
||||
void Warning<TSource>(Exception exception, string message, params object[] parameters);
|
||||
|
||||
void Warning(object source, Exception exception, string message, params object[] parameters);
|
||||
|
||||
void Error<TSource>(Exception exception, string message, params object[] parameters);
|
||||
|
||||
void Error(object source, Exception exception, string message, params object[] parameters);
|
||||
void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace MQTTnet.Diagnostics
|
||||
{
|
||||
public sealed class MqttNetChildLogger : IMqttNetChildLogger
|
||||
{
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly string _source;
|
||||
|
||||
public MqttNetChildLogger(IMqttNetLogger logger, string source)
|
||||
{
|
||||
_logger = logger;
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public IMqttNetChildLogger CreateChildLogger(string source)
|
||||
{
|
||||
string childSource;
|
||||
if (!string.IsNullOrEmpty(_source))
|
||||
{
|
||||
childSource = _source + "." + source;
|
||||
}
|
||||
else
|
||||
{
|
||||
childSource = source;
|
||||
}
|
||||
|
||||
return new MqttNetChildLogger(_logger, childSource);
|
||||
}
|
||||
|
||||
public void Verbose(string message, params object[] parameters)
|
||||
{
|
||||
_logger.Publish(MqttNetLogLevel.Verbose, _source, message, parameters, null);
|
||||
}
|
||||
|
||||
public void Info(string message, params object[] parameters)
|
||||
{
|
||||
_logger.Publish(MqttNetLogLevel.Info, _source, message, parameters, null);
|
||||
}
|
||||
|
||||
public void Warning(Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
_logger.Publish(MqttNetLogLevel.Warning, _source, message, parameters, exception);
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
_logger.Publish(MqttNetLogLevel.Error, _source, message, parameters, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace MQTTnet.Diagnostics
|
||||
{
|
||||
public class MqttNetLogger : IMqttNetLogger
|
||||
public sealed class MqttNetLogger : IMqttNetLogger
|
||||
{
|
||||
private readonly string _logId;
|
||||
|
||||
@@ -13,47 +13,12 @@ namespace MQTTnet.Diagnostics
|
||||
|
||||
public event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
||||
|
||||
public void Verbose<TSource>(string message, params object[] parameters)
|
||||
public IMqttNetChildLogger CreateChildLogger(string source)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Verbose, typeof(TSource), message, parameters, null);
|
||||
return new MqttNetChildLogger(this, source);
|
||||
}
|
||||
|
||||
public void Verbose(object source, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Verbose, source, message, parameters, null);
|
||||
}
|
||||
|
||||
public void Info<TSource>(string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Info, typeof(TSource), message, parameters, null);
|
||||
}
|
||||
|
||||
public void Info(object source, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Info, source, message, parameters, null);
|
||||
}
|
||||
|
||||
public void Warning<TSource>(Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Warning, typeof(TSource), message, parameters, null);
|
||||
}
|
||||
|
||||
public void Warning(object source, Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Warning, source, message, parameters, null);
|
||||
}
|
||||
|
||||
public void Error<TSource>(Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Error, typeof(TSource), message, parameters, null);
|
||||
}
|
||||
|
||||
public void Error(object source, Exception exception, string message, params object[] parameters)
|
||||
{
|
||||
Publish(MqttNetLogLevel.Error, source, message, parameters, null);
|
||||
}
|
||||
|
||||
private void Publish(MqttNetLogLevel logLevel, object source, string message, object[] parameters, Exception exception)
|
||||
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
|
||||
{
|
||||
var hasLocalListeners = LogMessagePublished != null;
|
||||
var hasGlobalListeners = MqttNetGlobalLogger.HasListeners;
|
||||
@@ -63,18 +28,19 @@ namespace MQTTnet.Diagnostics
|
||||
return;
|
||||
}
|
||||
|
||||
if (parameters.Length > 0)
|
||||
if (parameters?.Length > 0)
|
||||
{
|
||||
message = string.Format(message, parameters);
|
||||
try
|
||||
{
|
||||
message = string.Format(message, parameters);
|
||||
}
|
||||
catch
|
||||
{
|
||||
message = "MESSAGE FORMAT INVALID: " + message;
|
||||
}
|
||||
}
|
||||
|
||||
string sourceName = null;
|
||||
if (source != null)
|
||||
{
|
||||
sourceName = source.GetType().Name;
|
||||
}
|
||||
|
||||
var traceMessage = new MqttNetLogMessage(_logId, DateTime.Now, Environment.CurrentManagedThreadId, sourceName, logLevel, message, exception);
|
||||
var traceMessage = new MqttNetLogMessage(_logId, DateTime.UtcNow, Environment.CurrentManagedThreadId, source, logLevel, message, exception);
|
||||
|
||||
if (hasGlobalListeners)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace MQTTnet.Implementations
|
||||
{
|
||||
public class MqttClientAdapterFactory : IMqttClientAdapterFactory
|
||||
{
|
||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
|
||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||
|
||||
|
||||
@@ -11,12 +11,14 @@ namespace MQTTnet.Implementations
|
||||
{
|
||||
public class MqttTcpServerAdapter : IMqttServerAdapter
|
||||
{
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
private StreamSocketListener _defaultEndpointSocket;
|
||||
|
||||
public MqttTcpServerAdapter(IMqttNetLogger logger)
|
||||
public MqttTcpServerAdapter(IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
|
||||
}
|
||||
|
||||
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;
|
||||
@@ -74,7 +76,7 @@ namespace MQTTnet.Implementations
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
||||
_logger.Error(exception, "Error while accepting connection at default endpoint.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,18 @@ namespace MQTTnet.Implementations
|
||||
{
|
||||
public class MqttTcpServerAdapter : IMqttServerAdapter
|
||||
{
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private Socket _defaultEndpointSocket;
|
||||
private Socket _tlsEndpointSocket;
|
||||
private X509Certificate2 _tlsCertificate;
|
||||
|
||||
public MqttTcpServerAdapter(IMqttNetLogger logger)
|
||||
public MqttTcpServerAdapter(IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
|
||||
}
|
||||
|
||||
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;
|
||||
@@ -127,7 +129,7 @@ namespace MQTTnet.Implementations
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
||||
_logger.Error(exception, "Error while accepting connection at default endpoint.");
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +164,7 @@ namespace MQTTnet.Implementations
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at TLS endpoint.");
|
||||
_logger.Error(exception, "Error while accepting connection at TLS endpoint.");
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace MQTTnet.ManagedClient
|
||||
private readonly List<string> _unsubscriptions = new List<string>();
|
||||
|
||||
private readonly IMqttClient _mqttClient;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private CancellationTokenSource _connectionCancellationToken;
|
||||
private CancellationTokenSource _publishingCancellationToken;
|
||||
@@ -29,14 +29,17 @@ namespace MQTTnet.ManagedClient
|
||||
|
||||
private bool _subscriptionsNotPushed;
|
||||
|
||||
public ManagedMqttClient(IMqttClient mqttClient, IMqttNetLogger logger)
|
||||
public ManagedMqttClient(IMqttClient mqttClient, IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_mqttClient = mqttClient ?? throw new ArgumentNullException(nameof(mqttClient));
|
||||
|
||||
_mqttClient.Connected += OnConnected;
|
||||
_mqttClient.Disconnected += OnDisconnected;
|
||||
_mqttClient.ApplicationMessageReceived += OnApplicationMessageReceived;
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(ManagedMqttClient));
|
||||
}
|
||||
|
||||
public bool IsConnected => _mqttClient.IsConnected;
|
||||
@@ -74,7 +77,7 @@ namespace MQTTnet.ManagedClient
|
||||
Task.Run(() => MaintainConnectionAsync(_connectionCancellationToken.Token), _connectionCancellationToken.Token);
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
|
||||
_logger.Info<ManagedMqttClient>("Started");
|
||||
_logger.Info("Started");
|
||||
}
|
||||
|
||||
public Task StopAsync()
|
||||
@@ -166,12 +169,12 @@ namespace MQTTnet.ManagedClient
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while maintaining connection.");
|
||||
_logger.Error(exception, "Unhandled exception while maintaining connection.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await _mqttClient.DisconnectAsync().ConfigureAwait(false);
|
||||
_logger.Info<ManagedMqttClient>("Stopped");
|
||||
_logger.Info("Stopped");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,11 +207,11 @@ namespace MQTTnet.ManagedClient
|
||||
}
|
||||
catch (MqttCommunicationException exception)
|
||||
{
|
||||
_logger.Warning<ManagedMqttClient>(exception, "Communication exception while maintaining connection.");
|
||||
_logger.Warning(exception, "Communication exception while maintaining connection.");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while maintaining connection.");
|
||||
_logger.Error(exception, "Unhandled exception while maintaining connection.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,11 +240,11 @@ namespace MQTTnet.ManagedClient
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while publishing queued application messages.");
|
||||
_logger.Error(exception, "Unhandled exception while publishing queued application messages.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.Verbose<ManagedMqttClient>("Stopped publishing messages.");
|
||||
_logger.Verbose("Stopped publishing messages.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +264,7 @@ namespace MQTTnet.ManagedClient
|
||||
{
|
||||
transmitException = exception;
|
||||
|
||||
_logger.Warning<ManagedMqttClient>(exception, "Publishing application message failed.");
|
||||
_logger.Warning(exception, "Publishing application message failed.");
|
||||
|
||||
if (message.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
|
||||
{
|
||||
@@ -271,7 +274,7 @@ namespace MQTTnet.ManagedClient
|
||||
catch (Exception exception)
|
||||
{
|
||||
transmitException = exception;
|
||||
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while publishing queued application message.");
|
||||
_logger.Error(exception, "Unhandled exception while publishing queued application message.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -281,7 +284,7 @@ namespace MQTTnet.ManagedClient
|
||||
|
||||
private async Task SynchronizeSubscriptionsAsync()
|
||||
{
|
||||
_logger.Info<ManagedMqttClient>(nameof(ManagedMqttClient), "Synchronizing subscriptions");
|
||||
_logger.Info(nameof(ManagedMqttClient), "Synchronizing subscriptions");
|
||||
|
||||
List<TopicFilter> subscriptions;
|
||||
List<string> unsubscriptions;
|
||||
@@ -320,7 +323,7 @@ namespace MQTTnet.ManagedClient
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Warning<ManagedMqttClient>(exception, "Synchronizing subscriptions failed.");
|
||||
_logger.Warning(exception, "Synchronizing subscriptions failed.");
|
||||
_subscriptionsNotPushed = true;
|
||||
|
||||
SynchronizingSubscriptionsFailed?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
@@ -25,14 +25,14 @@ namespace MQTTnet
|
||||
|
||||
public IManagedMqttClient CreateManagedMqttClient()
|
||||
{
|
||||
return new ManagedMqttClient(CreateMqttClient(), new MqttNetLogger());
|
||||
return new ManagedMqttClient(CreateMqttClient(), new MqttNetLogger().CreateChildLogger(string.Empty));
|
||||
}
|
||||
|
||||
public IManagedMqttClient CreateManagedMqttClient(IMqttNetLogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
return new ManagedMqttClient(CreateMqttClient(), logger);
|
||||
return new ManagedMqttClient(CreateMqttClient(), logger.CreateChildLogger(string.Empty));
|
||||
}
|
||||
|
||||
public IMqttServer CreateMqttServer()
|
||||
@@ -45,7 +45,7 @@ namespace MQTTnet
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
return CreateMqttServer(new List<IMqttServerAdapter> { new MqttTcpServerAdapter(logger) }, logger);
|
||||
return CreateMqttServer(new List<IMqttServerAdapter> { new MqttTcpServerAdapter(logger.CreateChildLogger(string.Empty)) }, logger);
|
||||
}
|
||||
|
||||
public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
|
||||
@@ -53,7 +53,7 @@ namespace MQTTnet
|
||||
if (adapters == null) throw new ArgumentNullException(nameof(adapters));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
return new MqttServer(adapters, logger);
|
||||
return new MqttServer(adapters, logger.CreateChildLogger(string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,17 @@ namespace MQTTnet.Server
|
||||
|
||||
private readonly string _clientId;
|
||||
private readonly Action _timeoutCallback;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private Task _workerTask;
|
||||
|
||||
public MqttClientKeepAliveMonitor(string clientId, Action timeoutCallback, IMqttNetLogger logger)
|
||||
public MqttClientKeepAliveMonitor(string clientId, Action timeoutCallback, IMqttNetChildLogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_clientId = clientId;
|
||||
_timeoutCallback = timeoutCallback;
|
||||
_logger = logger;
|
||||
_logger = logger.CreateChildLogger(nameof(MqttClientKeepAliveMonitor));
|
||||
}
|
||||
|
||||
public TimeSpan LastPacketReceived => _lastPacketReceivedTracker.Elapsed;
|
||||
@@ -59,7 +61,7 @@ namespace MQTTnet.Server
|
||||
// Values described here: [MQTT-3.1.2-24].
|
||||
if (_lastPacketReceivedTracker.Elapsed.TotalSeconds > keepAlivePeriod * 1.5D)
|
||||
{
|
||||
_logger.Warning(this, null, "Client '{0}': Did not receive any packet or keep alive signal.", _clientId);
|
||||
_logger.Warning(null, "Client '{0}': Did not receive any packet or keep alive signal.", _clientId);
|
||||
|
||||
_timeoutCallback?.Invoke();
|
||||
|
||||
@@ -74,11 +76,11 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(this, exception, "Client '{0}': Unhandled exception while checking keep alive timeouts.", _clientId);
|
||||
_logger.Error(exception, "Client '{0}': Unhandled exception while checking keep alive timeouts.", _clientId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.Verbose(this, "Client {0}: Stopped checking keep alive timeout.", _clientId);
|
||||
_logger.Verbose("Client {0}: Stopped checking keep alive timeout.", _clientId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,15 +17,17 @@ namespace MQTTnet.Server
|
||||
private readonly AsyncAutoResetEvent _queueAutoResetEvent = new AsyncAutoResetEvent();
|
||||
private readonly IMqttServerOptions _options;
|
||||
private readonly MqttClientSession _clientSession;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private Task _workerTask;
|
||||
|
||||
public MqttClientPendingMessagesQueue(IMqttServerOptions options, MqttClientSession clientSession, IMqttNetLogger logger)
|
||||
public MqttClientPendingMessagesQueue(IMqttServerOptions options, MqttClientSession clientSession, IMqttNetChildLogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
_clientSession = clientSession ?? throw new ArgumentNullException(nameof(clientSession));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttClientPendingMessagesQueue));
|
||||
}
|
||||
|
||||
public int Count => _queue.Count;
|
||||
@@ -70,7 +72,7 @@ namespace MQTTnet.Server
|
||||
_queue.Enqueue(packet);
|
||||
_queueAutoResetEvent.Set();
|
||||
|
||||
_logger.Verbose(this, "Enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
||||
_logger.Verbose("Enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
|
||||
private async Task SendQueuedPacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||
@@ -87,7 +89,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(this, exception, "Unhandled exception while sending enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
||||
_logger.Error(exception, "Unhandled exception while sending enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,25 +115,24 @@ namespace MQTTnet.Server
|
||||
|
||||
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, new[] { packet }, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
_logger.Verbose<MqttClientPendingMessagesQueue>("Enqueued packet sent (ClientId: {0}).",
|
||||
_clientSession.ClientId);
|
||||
_logger.Verbose("Enqueued packet sent (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is MqttCommunicationTimedOutException)
|
||||
{
|
||||
_logger.Warning(this, exception, "Sending publish packet failed: Timeout (ClientId: {0}).", _clientSession.ClientId);
|
||||
_logger.Warning(exception, "Sending publish packet failed: Timeout (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
else if (exception is MqttCommunicationException)
|
||||
{
|
||||
_logger.Warning(this, exception, "Sending publish packet failed: Communication exception (ClientId: {0}).", _clientSession.ClientId);
|
||||
_logger.Warning(exception, "Sending publish packet failed: Communication exception (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
else if (exception is OperationCanceledException)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error(this, exception, "Sending publish packet failed (ClientId: {0}).", _clientSession.ClientId);
|
||||
_logger.Error(exception, "Sending publish packet failed (ClientId: {0}).", _clientSession.ClientId);
|
||||
}
|
||||
|
||||
if (packet is MqttPublishPacket publishPacket)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MQTTnet.Server
|
||||
{
|
||||
private readonly MqttPacketIdentifierProvider _packetIdentifierProvider = new MqttPacketIdentifierProvider();
|
||||
private readonly MqttRetainedMessagesManager _retainedMessagesManager;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
private readonly IMqttServerOptions _options;
|
||||
private readonly MqttClientSessionsManager _sessionsManager;
|
||||
|
||||
@@ -30,15 +30,18 @@ namespace MQTTnet.Server
|
||||
IMqttServerOptions options,
|
||||
MqttClientSessionsManager sessionsManager,
|
||||
MqttRetainedMessagesManager retainedMessagesManager,
|
||||
IMqttNetLogger logger)
|
||||
IMqttNetChildLogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
_sessionsManager = sessionsManager;
|
||||
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
|
||||
ClientId = clientId;
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttClientSession));
|
||||
|
||||
KeepAliveMonitor = new MqttClientKeepAliveMonitor(clientId, StopDueToKeepAliveTimeout, _logger);
|
||||
SubscriptionsManager = new MqttClientSubscriptionsManager(clientId, _options, sessionsManager.Server);
|
||||
PendingMessagesQueue = new MqttClientPendingMessagesQueue(_options, this, _logger);
|
||||
@@ -81,13 +84,11 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (MqttCommunicationException exception)
|
||||
{
|
||||
_logger.Warning<MqttClientSession>(exception,
|
||||
"Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
_logger.Warning(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttClientSession>(exception,
|
||||
"Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
_logger.Error(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -126,7 +127,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.Info<MqttClientSession>("Client '{0}': Session stopped.", ClientId);
|
||||
_logger.Info("Client '{0}': Session stopped.", ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +186,7 @@ namespace MQTTnet.Server
|
||||
|
||||
private void StopDueToKeepAliveTimeout()
|
||||
{
|
||||
_logger.Info<MqttClientSession>("Client '{0}': Timeout while waiting for KeepAlive packet.", ClientId);
|
||||
_logger.Info("Client '{0}': Timeout while waiting for KeepAlive packet.", ClientId);
|
||||
Stop(MqttClientDisconnectType.NotClean);
|
||||
}
|
||||
|
||||
@@ -207,11 +208,11 @@ namespace MQTTnet.Server
|
||||
{
|
||||
if (exception is MqttCommunicationException)
|
||||
{
|
||||
_logger.Warning<MqttClientSession>(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
_logger.Warning(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error<MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
_logger.Error(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||
}
|
||||
|
||||
Stop(MqttClientDisconnectType.NotClean);
|
||||
@@ -273,7 +274,7 @@ namespace MQTTnet.Server
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
_logger.Warning(this, null, "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
||||
_logger.Warning(null, "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
||||
Stop(MqttClientDisconnectType.NotClean);
|
||||
|
||||
return Task.FromResult(0);
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
@@ -14,15 +15,18 @@ namespace MQTTnet.Server
|
||||
public sealed class MqttClientSessionsManager : IDisposable
|
||||
{
|
||||
private readonly Dictionary<string, MqttClientSession> _sessions = new Dictionary<string, MqttClientSession>();
|
||||
private readonly SemaphoreSlim _sessionsLock = new SemaphoreSlim(1, 1);
|
||||
private readonly AsyncLock _sessionsLock = new AsyncLock();
|
||||
|
||||
private readonly MqttRetainedMessagesManager _retainedMessagesManager;
|
||||
private readonly IMqttServerOptions _options;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
public MqttClientSessionsManager(IMqttServerOptions options, MqttServer server, MqttRetainedMessagesManager retainedMessagesManager, IMqttNetLogger logger)
|
||||
public MqttClientSessionsManager(IMqttServerOptions options, MqttServer server, MqttRetainedMessagesManager retainedMessagesManager, IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
_logger = logger.CreateChildLogger(nameof(MqttClientSessionsManager));
|
||||
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
Server = server ?? throw new ArgumentNullException(nameof(server));
|
||||
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
|
||||
@@ -89,7 +93,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttClientSessionsManager>(exception, exception.Message);
|
||||
_logger.Error(exception, exception.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -100,7 +104,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttClientSessionsManager>(exception, exception.Message);
|
||||
_logger.Error(exception, exception.Message);
|
||||
}
|
||||
|
||||
Server.OnClientDisconnected(new ConnectedMqttClient
|
||||
@@ -115,7 +119,7 @@ namespace MQTTnet.Server
|
||||
|
||||
public async Task StopAsync()
|
||||
{
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
foreach (var session in _sessions)
|
||||
@@ -127,13 +131,13 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IList<ConnectedMqttClient>> GetConnectedClientsAsync()
|
||||
{
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
return _sessions.Where(s => s.Value.IsConnected).Select(s => new ConnectedMqttClient
|
||||
@@ -147,7 +151,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +165,7 @@ namespace MQTTnet.Server
|
||||
if (clientId == null) throw new ArgumentNullException(nameof(clientId));
|
||||
if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
|
||||
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (!_sessions.TryGetValue(clientId, out var session))
|
||||
@@ -173,7 +177,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +186,7 @@ namespace MQTTnet.Server
|
||||
if (clientId == null) throw new ArgumentNullException(nameof(clientId));
|
||||
if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
|
||||
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (!_sessions.TryGetValue(clientId, out var session))
|
||||
@@ -194,7 +198,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +226,7 @@ namespace MQTTnet.Server
|
||||
|
||||
private async Task<GetOrCreateClientSessionResult> PrepareClientSessionAsync(MqttConnectPacket connectPacket)
|
||||
{
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var isSessionPresent = _sessions.TryGetValue(connectPacket.ClientId, out var clientSession);
|
||||
@@ -236,11 +240,11 @@ namespace MQTTnet.Server
|
||||
clientSession.Dispose();
|
||||
clientSession = null;
|
||||
|
||||
_logger.Verbose<MqttClientSessionsManager>("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Verbose("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Verbose<MqttClientSessionsManager>("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,14 +256,14 @@ namespace MQTTnet.Server
|
||||
clientSession = new MqttClientSession(connectPacket.ClientId, _options, this, _retainedMessagesManager, _logger);
|
||||
_sessions[connectPacket.ClientId] = clientSession;
|
||||
|
||||
_logger.Verbose<MqttClientSessionsManager>("Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||
_logger.Verbose("Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||
}
|
||||
|
||||
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,10 +291,10 @@ namespace MQTTnet.Server
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttClientSessionsManager>(exception, "Error while processing application message");
|
||||
_logger.Error(exception, "Error while processing application message");
|
||||
}
|
||||
|
||||
await _sessionsLock.WaitAsync().ConfigureAwait(false);
|
||||
await _sessionsLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
foreach (var clientSession in _sessions.Values)
|
||||
@@ -300,7 +304,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sessionsLock.Release();
|
||||
_sessionsLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,21 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public sealed class MqttRetainedMessagesManager : IDisposable
|
||||
{
|
||||
private readonly Dictionary<string, MqttApplicationMessage> _retainedMessages = new Dictionary<string, MqttApplicationMessage>();
|
||||
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly Dictionary<string, MqttApplicationMessage> _messages = new Dictionary<string, MqttApplicationMessage>();
|
||||
private readonly AsyncLock _messagesLock = new AsyncLock();
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
private readonly IMqttServerOptions _options;
|
||||
|
||||
public MqttRetainedMessagesManager(IMqttServerOptions options, IMqttNetLogger logger)
|
||||
public MqttRetainedMessagesManager(IMqttServerOptions options, IMqttNetChildLogger logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
_logger = logger.CreateChildLogger(nameof(MqttRetainedMessagesManager));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
@@ -27,24 +29,24 @@ namespace MQTTnet.Server
|
||||
return;
|
||||
}
|
||||
|
||||
await _semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await _messagesLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var retainedMessages = await _options.Storage.LoadRetainedMessagesAsync();
|
||||
var retainedMessages = await _options.Storage.LoadRetainedMessagesAsync().ConfigureAwait(false);
|
||||
|
||||
_retainedMessages.Clear();
|
||||
_messages.Clear();
|
||||
foreach (var retainedMessage in retainedMessages)
|
||||
{
|
||||
_retainedMessages[retainedMessage.Topic] = retainedMessage;
|
||||
_messages[retainedMessage.Topic] = retainedMessage;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttRetainedMessagesManager>(exception, "Unhandled exception while loading retained messages.");
|
||||
_logger.Error(exception, "Unhandled exception while loading retained messages.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
_messagesLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,18 +54,18 @@ namespace MQTTnet.Server
|
||||
{
|
||||
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
||||
|
||||
await _semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await _messagesLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await HandleMessageInternalAsync(clientId, applicationMessage);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error<MqttRetainedMessagesManager>(exception, "Unhandled exception while handling retained messages.");
|
||||
_logger.Error(exception, "Unhandled exception while handling retained messages.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
_messagesLock.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,10 +73,10 @@ namespace MQTTnet.Server
|
||||
{
|
||||
var retainedMessages = new List<MqttApplicationMessage>();
|
||||
|
||||
await _semaphore.WaitAsync().ConfigureAwait(false);
|
||||
await _messagesLock.EnterAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
foreach (var retainedMessage in _retainedMessages.Values)
|
||||
foreach (var retainedMessage in _messages.Values)
|
||||
{
|
||||
foreach (var topicFilter in topicFilters)
|
||||
{
|
||||
@@ -90,7 +92,7 @@ namespace MQTTnet.Server
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
_messagesLock.Exit();
|
||||
}
|
||||
|
||||
return retainedMessages;
|
||||
@@ -98,7 +100,7 @@ namespace MQTTnet.Server
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_semaphore?.Dispose();
|
||||
_messagesLock?.Dispose();
|
||||
}
|
||||
|
||||
private async Task HandleMessageInternalAsync(string clientId, MqttApplicationMessage applicationMessage)
|
||||
@@ -107,37 +109,37 @@ namespace MQTTnet.Server
|
||||
|
||||
if (applicationMessage.Payload?.Any() == false)
|
||||
{
|
||||
saveIsRequired = _retainedMessages.Remove(applicationMessage.Topic);
|
||||
_logger.Info<MqttRetainedMessagesManager>("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||
_logger.Info("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_retainedMessages.ContainsKey(applicationMessage.Topic))
|
||||
if (!_messages.ContainsKey(applicationMessage.Topic))
|
||||
{
|
||||
_retainedMessages[applicationMessage.Topic] = applicationMessage;
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var existingMessage = _retainedMessages[applicationMessage.Topic];
|
||||
var existingMessage = _messages[applicationMessage.Topic];
|
||||
if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !existingMessage.Payload.SequenceEqual(applicationMessage.Payload ?? new byte[0]))
|
||||
{
|
||||
_retainedMessages[applicationMessage.Topic] = applicationMessage;
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Info<MqttRetainedMessagesManager>("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
_logger.Info("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
|
||||
if (!saveIsRequired)
|
||||
{
|
||||
_logger.Verbose<MqttRetainedMessagesManager>("Skipped saving retained messages because no changes were detected.");
|
||||
_logger.Verbose("Skipped saving retained messages because no changes were detected.");
|
||||
}
|
||||
|
||||
if (saveIsRequired && _options.Storage != null)
|
||||
{
|
||||
await _options.Storage.SaveRetainedMessagesAsync(_retainedMessages.Values.ToList());
|
||||
await _options.Storage.SaveRetainedMessagesAsync(_messages.Values.ToList()).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,17 @@ namespace MQTTnet.Server
|
||||
public class MqttServer : IMqttServer
|
||||
{
|
||||
private readonly ICollection<IMqttServerAdapter> _adapters;
|
||||
private readonly IMqttNetLogger _logger;
|
||||
private readonly IMqttNetChildLogger _logger;
|
||||
|
||||
private MqttClientSessionsManager _clientSessionsManager;
|
||||
private MqttRetainedMessagesManager _retainedMessagesManager;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
public MqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
|
||||
public MqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetChildLogger logger)
|
||||
{
|
||||
if (adapters == null) throw new ArgumentNullException(nameof(adapters));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
_logger = logger.CreateChildLogger(nameof(MqttServer));
|
||||
|
||||
_adapters = adapters.ToList();
|
||||
}
|
||||
@@ -90,7 +91,7 @@ namespace MQTTnet.Server
|
||||
await adapter.StartAsync(Options);
|
||||
}
|
||||
|
||||
_logger.Info<MqttServer>("Started.");
|
||||
_logger.Info("Started.");
|
||||
Started?.Invoke(this, new MqttServerStartedEventArgs());
|
||||
}
|
||||
|
||||
@@ -114,7 +115,7 @@ namespace MQTTnet.Server
|
||||
|
||||
await _clientSessionsManager.StopAsync();
|
||||
|
||||
_logger.Info<MqttServer>("Stopped.");
|
||||
_logger.Info("Stopped.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -129,13 +130,13 @@ namespace MQTTnet.Server
|
||||
|
||||
internal void OnClientConnected(ConnectedMqttClient client)
|
||||
{
|
||||
_logger.Info<MqttServer>("Client '{0}': Connected.", client.ClientId);
|
||||
_logger.Info("Client '{0}': Connected.", client.ClientId);
|
||||
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(client));
|
||||
}
|
||||
|
||||
internal void OnClientDisconnected(ConnectedMqttClient client, bool wasCleanDisconnect)
|
||||
{
|
||||
_logger.Info<MqttServer>("Client '{0}': Disconnected (clean={1}).", client.ClientId, wasCleanDisconnect);
|
||||
_logger.Info("Client '{0}': Disconnected (clean={1}).", client.ClientId, wasCleanDisconnect);
|
||||
ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(client, wasCleanDisconnect));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Attributes.Exporters;
|
||||
using BenchmarkDotNet.Attributes.Jobs;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
namespace MQTTnet.Benchmarks
|
||||
{
|
||||
[ClrJob]
|
||||
[RPlotExporter]
|
||||
[MemoryDiagnoser]
|
||||
public class LoggerBenchmark
|
||||
{
|
||||
private IMqttNetLogger _logger;
|
||||
private IMqttNetChildLogger _childLogger;
|
||||
private bool _useHandler;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
_logger = new MqttNetLogger("1");
|
||||
_childLogger = _logger.CreateChildLogger("child");
|
||||
|
||||
MqttNetGlobalLogger.LogMessagePublished += OnLogMessagePublished;
|
||||
}
|
||||
|
||||
private void OnLogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs eventArgs)
|
||||
{
|
||||
if (_useHandler)
|
||||
{
|
||||
eventArgs.TraceMessage.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Log_10000_Messages_NoHandler()
|
||||
{
|
||||
_useHandler = false;
|
||||
for (var i = 0; i < 10000; i++)
|
||||
{
|
||||
_childLogger.Verbose("test log message {0}", "parameter");
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Log_10000_Messages_WithHandler()
|
||||
{
|
||||
_useHandler = true;
|
||||
for (var i = 0; i < 10000; i++)
|
||||
{
|
||||
_childLogger.Verbose("test log message {0}", "parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,6 +147,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="LoggerBenchmark.cs" />
|
||||
<Compile Include="MessageProcessingBenchmark.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using BenchmarkDotNet.Running;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
@@ -12,6 +11,7 @@ namespace MQTTnet.Benchmarks
|
||||
Console.WriteLine($"MQTTnet - BenchmarkApp.{TargetFrameworkInfoProvider.TargetFramework}");
|
||||
Console.WriteLine("1 = MessageProcessingBenchmark");
|
||||
Console.WriteLine("2 = SerializerBenchmark");
|
||||
Console.WriteLine("3 = LoggerBenchmark");
|
||||
|
||||
var pressedKey = Console.ReadKey(true);
|
||||
switch (pressedKey.KeyChar)
|
||||
@@ -22,7 +22,8 @@ namespace MQTTnet.Benchmarks
|
||||
case '2':
|
||||
BenchmarkRunner.Run<SerializerBenchmark>();
|
||||
break;
|
||||
default:
|
||||
case '3':
|
||||
BenchmarkRunner.Run<LoggerBenchmark>();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Serializer;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Server;
|
||||
using BenchmarkDotNet.Attributes.Jobs;
|
||||
using BenchmarkDotNet.Attributes.Exporters;
|
||||
using System;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MQTTnet.Core.Tests
|
||||
var monitor = new MqttClientKeepAliveMonitor(string.Empty, delegate
|
||||
{
|
||||
timeoutCalledCount++;
|
||||
}, new MqttNetLogger());
|
||||
}, new MqttNetLogger().CreateChildLogger(""));
|
||||
|
||||
Assert.AreEqual(0, timeoutCalledCount);
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace MQTTnet.Core.Tests
|
||||
var monitor = new MqttClientKeepAliveMonitor(string.Empty, delegate
|
||||
{
|
||||
timeoutCalledCount++;
|
||||
}, new MqttNetLogger());
|
||||
}, new MqttNetLogger().CreateChildLogger(""));
|
||||
|
||||
Assert.AreEqual(0, timeoutCalledCount);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Tests
|
||||
[TestMethod]
|
||||
public void MqttSubscriptionsManager_SubscribeSingleSuccess()
|
||||
{
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger()));
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger().CreateChildLogger("")));
|
||||
|
||||
var sp = new MqttSubscribePacket();
|
||||
sp.TopicFilters.Add(new TopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||
@@ -34,7 +34,7 @@ namespace MQTTnet.Core.Tests
|
||||
[TestMethod]
|
||||
public void MqttSubscriptionsManager_SubscribeDifferentQoSSuccess()
|
||||
{
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger()));
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger().CreateChildLogger("")));
|
||||
|
||||
var sp = new MqttSubscribePacket();
|
||||
sp.TopicFilters.Add(new TopicFilter("A/B/C", MqttQualityOfServiceLevel.AtMostOnce));
|
||||
@@ -55,7 +55,7 @@ namespace MQTTnet.Core.Tests
|
||||
[TestMethod]
|
||||
public void MqttSubscriptionsManager_SubscribeTwoTimesSuccess()
|
||||
{
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger()));
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger().CreateChildLogger("")));
|
||||
|
||||
var sp = new MqttSubscribePacket();
|
||||
sp.TopicFilters.Add(new TopicFilter("#", MqttQualityOfServiceLevel.AtMostOnce));
|
||||
@@ -77,7 +77,7 @@ namespace MQTTnet.Core.Tests
|
||||
[TestMethod]
|
||||
public void MqttSubscriptionsManager_SubscribeSingleNoSuccess()
|
||||
{
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger()));
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger().CreateChildLogger("")));
|
||||
|
||||
var sp = new MqttSubscribePacket();
|
||||
sp.TopicFilters.Add(new TopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||
@@ -96,7 +96,7 @@ namespace MQTTnet.Core.Tests
|
||||
[TestMethod]
|
||||
public void MqttSubscriptionsManager_SubscribeAndUnsubscribeSingle()
|
||||
{
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger()));
|
||||
var sm = new MqttClientSubscriptionsManager("", new MqttServerOptions(), new MqttServer(new IMqttServerAdapter[0], new MqttNetLogger().CreateChildLogger("")));
|
||||
|
||||
var sp = new MqttSubscribePacket();
|
||||
sp.TopicFilters.Add(new TopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Tests
|
||||
_adapter = adapter;
|
||||
}
|
||||
|
||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
|
||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
|
||||
{
|
||||
return _adapter;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user