diff --git a/Build/MQTTnet.AspNetCore.nuspec b/Build/MQTTnet.AspNetCore.nuspec
index a46cd81..61fc121 100644
--- a/Build/MQTTnet.AspNetCore.nuspec
+++ b/Build/MQTTnet.AspNetCore.nuspec
@@ -11,15 +11,15 @@
false
This is a support library to integrate MQTTnet into AspNetCore.
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- Copyright Christian Kratky 2016-2019
+ Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
-
-
-
-
+
+
+
+
diff --git a/Build/MQTTnet.Extensions.ManagedClient.nuspec b/Build/MQTTnet.Extensions.ManagedClient.nuspec
index edec769..8ae373f 100644
--- a/Build/MQTTnet.Extensions.ManagedClient.nuspec
+++ b/Build/MQTTnet.Extensions.ManagedClient.nuspec
@@ -11,7 +11,7 @@
false
This is an extension library which provides a managed MQTT client with additional features using MQTTnet.
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- Copyright Christian Kratky 2016-2019
+ Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
diff --git a/Build/MQTTnet.Extensions.Rpc.nuspec b/Build/MQTTnet.Extensions.Rpc.nuspec
index ce81cb6..4089ae4 100644
--- a/Build/MQTTnet.Extensions.Rpc.nuspec
+++ b/Build/MQTTnet.Extensions.Rpc.nuspec
@@ -11,7 +11,7 @@
false
This is an extension library which allows executing synchronous device calls including a response using MQTTnet.
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- Copyright Christian Kratky 2016-2019
+ Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
diff --git a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec
index 054933e..0baacdd 100644
--- a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec
+++ b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec
@@ -11,7 +11,7 @@
false
This is an extension library which allows using _WebSocket4Net_ as transport for MQTTnet clients.
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- Copyright Christian Kratky 2016-2019
+ Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
diff --git a/Build/MQTTnet.NETStandard.nuspec b/Build/MQTTnet.NETStandard.nuspec
index c505dd1..ef1b3fa 100644
--- a/Build/MQTTnet.NETStandard.nuspec
+++ b/Build/MQTTnet.NETStandard.nuspec
@@ -11,7 +11,7 @@
false
This package contains the .NET Standard version of MQTTnet only.
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- Copyright Christian Kratky 2016-2019
+ Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec
index 10c7280..9e25687 100644
--- a/Build/MQTTnet.nuspec
+++ b/Build/MQTTnet.nuspec
@@ -12,17 +12,23 @@
MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.
* [All] Due to a merge issue not all changes are included in 3.0.8. All these changes are now included in this version.
+* [Core] Updated all nuget references.
+* [Core] Added MqttApplicationMessage.GetUserProperty() convenience method (thanks to @PMExtra).
+* [LowLevelMqttClient] Added low level MQTT client in order to provide more flexibility when using the MQTT protocol. This client requires detailed knowledge about the MQTT protocol.
+* [Client] Improve connection stability (thanks to @jltjohanlindqvist).
+* [Client] Support WithConnectionUri to configure client (thanks to @PMExtra).
* [ManagedClient] Added builder class for MqttClientUnsubscribeOptions (thanks to @dominikviererbe).
* [ManagedClient] Added support for persisted sessions (thansk to @PMExtra).
-* [Client] Improve connection stability (thanks to @jltjohanlindqvist).
* [ManagedClient] Fixed a memory leak (thanks to @zawodskoj).
* [ManagedClient] Improved internal subscription management (#569, thanks to @cstichlberger).
* [ManagedClient] Refactored log messages (thanks to @cstichlberger).
* [Server] Added support for assigned client IDs (MQTTv5 only) (thanks to @bcrosnier).
* [Server] Added interceptor for unsubscriptions.
-* [MQTTnet.Server] Added interceptor for unsubscriptions.
+* [Server] Removed exceptions when user properties are set with MQTT protocol version 3.1
+* [Server] Added custom session items to the client status.
+* [Server] Added option to check whether the server is already started properly or not.
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1
-* [MQTTnet.Server] Added option to check whether the server is already started properly or not.
+* [MQTTnet.Server] Added interceptor for unsubscriptions.
Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
@@ -40,7 +46,7 @@
-
+
diff --git a/MQTTnet.sln b/MQTTnet.sln
index 22fd0ad..ebbe8cd 100644
--- a/MQTTnet.sln
+++ b/MQTTnet.sln
@@ -53,6 +53,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQ
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.WebSocket4Net", "Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj", "{2BD01D53-4CA5-4142-BE8D-313876395E3E}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{A56E3128-1639-4F31-873A-325E14BB6295}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -270,7 +272,7 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
- {FF1F72D6-9524-4422-9497-3CC0002216ED} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {FF1F72D6-9524-4422-9497-3CC0002216ED} = {A56E3128-1639-4F31-873A-325E14BB6295}
{3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB}
{3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
@@ -279,7 +281,7 @@ Global
{998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
- {5699FB8C-838C-4AB0-80A5-9CA809F9B65B} = {32A630A7-2598-41D7-B625-204CD906F5FB}
+ {5699FB8C-838C-4AB0-80A5-9CA809F9B65B} = {A56E3128-1639-4F31-873A-325E14BB6295}
{2BD01D53-4CA5-4142-BE8D-313876395E3E} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
diff --git a/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs b/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
index e8f570c..44acb77 100644
--- a/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
+++ b/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
@@ -1,17 +1,16 @@
-using System;
-using System.Net;
-using MQTTnet.Adapter;
+using MQTTnet.Adapter;
using MQTTnet.AspNetCore.Client.Tcp;
-using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
+using System;
+using System.Net;
namespace MQTTnet.AspNetCore.Client
{
public class MqttClientConnectionContextFactory : IMqttClientAdapterFactory
{
- public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
+ public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
diff --git a/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs
index 8606142..84a10d4 100644
--- a/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs
+++ b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs
@@ -1,10 +1,10 @@
-using System;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
-using MQTTnet.Server;
using MQTTnet.Implementations;
-using Microsoft.Extensions.DependencyInjection;
+using MQTTnet.Server;
+using System;
namespace MQTTnet.AspNetCore
{
@@ -13,7 +13,7 @@ namespace MQTTnet.AspNetCore
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, IMqttServerOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
-
+
services.AddSingleton(options);
services.AddHostedMqttServer();
@@ -23,7 +23,8 @@ namespace MQTTnet.AspNetCore
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, Action configure)
{
- services.AddSingleton(s => {
+ services.AddSingleton(s =>
+ {
var builder = new MqttServerOptionsBuilder();
configure(builder);
return builder.Build();
@@ -36,7 +37,8 @@ namespace MQTTnet.AspNetCore
public static IServiceCollection AddHostedMqttServerWithServices(this IServiceCollection services, Action configure)
{
- services.AddSingleton(s => {
+ services.AddSingleton(s =>
+ {
var builder = new AspNetMqttServerOptionsBuilder(s);
configure(builder);
return builder.Build();
@@ -60,14 +62,12 @@ namespace MQTTnet.AspNetCore
private static IServiceCollection AddHostedMqttServer(this IServiceCollection services)
{
var logger = new MqttNetLogger();
- var childLogger = logger.CreateChildLogger();
services.AddSingleton(logger);
- services.AddSingleton(childLogger);
services.AddSingleton();
services.AddSingleton(s => s.GetService());
services.AddSingleton(s => s.GetService());
-
+
return services;
}
diff --git a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
index e6f0582..ff0fbf9 100644
--- a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
+++ b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
@@ -21,10 +21,10 @@
-
-
-
-
+
+
+
+
diff --git a/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs b/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
index a052dae..8e0134c 100644
--- a/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
+++ b/Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
@@ -1,20 +1,20 @@
-using System;
-using System.Net.WebSockets;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
using MQTTnet.Implementations;
using MQTTnet.Server;
+using System;
+using System.Net.WebSockets;
+using System.Threading.Tasks;
namespace MQTTnet.AspNetCore
{
public class MqttWebSocketServerAdapter : IMqttServerAdapter
{
- private readonly IMqttNetChildLogger _logger;
+ private readonly IMqttNetLogger _logger;
- public MqttWebSocketServerAdapter(IMqttNetChildLogger logger)
+ public MqttWebSocketServerAdapter(IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -38,7 +38,7 @@ namespace MQTTnet.AspNetCore
if (webSocket == null) throw new ArgumentNullException(nameof(webSocket));
var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";
-
+
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);
try
{
diff --git a/Source/MQTTnet.Extensions.ManagedClient/ManagedMqttClient.cs b/Source/MQTTnet.Extensions.ManagedClient/ManagedMqttClient.cs
index 8b5a48f..10d7d77 100644
--- a/Source/MQTTnet.Extensions.ManagedClient/ManagedMqttClient.cs
+++ b/Source/MQTTnet.Extensions.ManagedClient/ManagedMqttClient.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MQTTnet.Client;
+using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Publishing;
@@ -13,6 +8,11 @@ using MQTTnet.Exceptions;
using MQTTnet.Internal;
using MQTTnet.Protocol;
using MQTTnet.Server;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
namespace MQTTnet.Extensions.ManagedClient
{
@@ -33,7 +33,7 @@ namespace MQTTnet.Extensions.ManagedClient
private readonly SemaphoreSlim _subscriptionsQueuedSignal = new SemaphoreSlim(0);
private readonly IMqttClient _mqttClient;
- private readonly IMqttNetChildLogger _logger;
+ private readonly IMqttNetLogger _logger;
private readonly AsyncLock _messageQueueLock = new AsyncLock();
@@ -42,8 +42,8 @@ namespace MQTTnet.Extensions.ManagedClient
private Task _maintainConnectionTask;
private ManagedMqttClientStorageManager _storageManager;
-
- public ManagedMqttClient(IMqttClient mqttClient, IMqttNetChildLogger logger)
+
+ public ManagedMqttClient(IMqttClient mqttClient, IMqttNetLogger logger)
{
_mqttClient = mqttClient ?? throw new ArgumentNullException(nameof(mqttClient));
diff --git a/Source/MQTTnet.Extensions.ManagedClient/MqttFactoryExtensions.cs b/Source/MQTTnet.Extensions.ManagedClient/MqttFactoryExtensions.cs
index 37393ac..b0fd882 100644
--- a/Source/MQTTnet.Extensions.ManagedClient/MqttFactoryExtensions.cs
+++ b/Source/MQTTnet.Extensions.ManagedClient/MqttFactoryExtensions.cs
@@ -1,5 +1,5 @@
-using System;
-using MQTTnet.Diagnostics;
+using MQTTnet.Diagnostics;
+using System;
namespace MQTTnet.Extensions.ManagedClient
{
@@ -9,7 +9,7 @@ namespace MQTTnet.Extensions.ManagedClient
{
if (factory == null) throw new ArgumentNullException(nameof(factory));
- return new ManagedMqttClient(factory.CreateMqttClient(), factory.DefaultLogger.CreateChildLogger());
+ return new ManagedMqttClient(factory.CreateMqttClient(), factory.DefaultLogger);
}
public static IManagedMqttClient CreateManagedMqttClient(this IMqttFactory factory, IMqttNetLogger logger)
@@ -17,7 +17,7 @@ namespace MQTTnet.Extensions.ManagedClient
if (factory == null) throw new ArgumentNullException(nameof(factory));
if (logger == null) throw new ArgumentNullException(nameof(logger));
- return new ManagedMqttClient(factory.CreateMqttClient(logger), logger.CreateChildLogger());
+ return new ManagedMqttClient(factory.CreateMqttClient(logger), logger);
}
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs b/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs
index 7625fc9..1c3a9c6 100644
--- a/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs
+++ b/Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttClientAdapterFactory.cs
@@ -1,15 +1,15 @@
-using System;
-using MQTTnet.Adapter;
+using MQTTnet.Adapter;
using MQTTnet.Client.Options;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
using MQTTnet.Implementations;
+using System;
namespace MQTTnet.Extensions.WebSocket4Net
{
public class WebSocket4NetMqttClientAdapterFactory : IMqttClientAdapterFactory
{
- public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
+ public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -17,19 +17,19 @@ namespace MQTTnet.Extensions.WebSocket4Net
switch (options.ChannelOptions)
{
case MqttClientTcpOptions _:
- {
- return new MqttChannelAdapter(new MqttTcpChannel(options), new MqttPacketFormatterAdapter(options.ProtocolVersion), logger);
- }
+ {
+ return new MqttChannelAdapter(new MqttTcpChannel(options), new MqttPacketFormatterAdapter(options.ProtocolVersion), logger);
+ }
case MqttClientWebSocketOptions webSocketOptions:
- {
- return new MqttChannelAdapter(new WebSocket4NetMqttChannel(options, webSocketOptions), new MqttPacketFormatterAdapter(options.ProtocolVersion), logger);
- }
+ {
+ return new MqttChannelAdapter(new WebSocket4NetMqttChannel(options, webSocketOptions), new MqttPacketFormatterAdapter(options.ProtocolVersion), logger);
+ }
default:
- {
- throw new NotSupportedException();
- }
+ {
+ throw new NotSupportedException();
+ }
}
}
}
diff --git a/Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs b/Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs
index 7f35117..656239f 100644
--- a/Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs
+++ b/Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs
@@ -1,43 +1,43 @@
-using System;
-using MQTTnet.Diagnostics;
-
-namespace MQTTnet.Server.Logging
-{
- public class MqttNetChildLoggerWrapper : IMqttNetChildLogger
- {
- private readonly MqttNetLoggerWrapper _logger;
- private readonly string _source;
-
- public MqttNetChildLoggerWrapper(string source, MqttNetLoggerWrapper logger)
- {
- _logger = logger ?? throw new ArgumentNullException(nameof(logger));
-
- _source = source;
- }
-
- public IMqttNetChildLogger CreateChildLogger(string source = null)
- {
- return _logger.CreateChildLogger(source);
- }
-
- 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);
- }
- }
-}
+//using MQTTnet.Diagnostics;
+//using System;
+
+//namespace MQTTnet.Server.Logging
+//{
+// public class MqttNetChildLoggerWrapper : IMqttNetChildLogger
+// {
+// private readonly MqttNetLoggerWrapper _logger;
+// private readonly string _source;
+
+// public MqttNetChildLoggerWrapper(string source, MqttNetLoggerWrapper logger)
+// {
+// _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+
+// _source = source;
+// }
+
+// public IMqttNetLogger CreateChildLogger(string source = null)
+// {
+// return _logger.CreateChildLogger(source);
+// }
+
+// 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);
+// }
+// }
+//}
diff --git a/Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs b/Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs
index 3f52109..9c71e28 100644
--- a/Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs
+++ b/Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs
@@ -1,13 +1,13 @@
-using System;
-using System.Threading;
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging;
using MQTTnet.Diagnostics;
+using System;
+using System.Threading;
namespace MQTTnet.Server.Logging
{
public class MqttNetLoggerWrapper : IMqttNetLogger
{
- private readonly ILogger _logger;
+ readonly ILogger _logger;
public MqttNetLoggerWrapper(ILogger logger)
{
@@ -16,25 +16,39 @@ namespace MQTTnet.Server.Logging
public event EventHandler LogMessagePublished;
- public IMqttNetChildLogger CreateChildLogger(string source = null)
+ public IMqttNetLogger CreateChildLogger(string source)
{
- return new MqttNetChildLoggerWrapper(source, this);
+ return new MqttNetLogger(source);
}
- public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
+ public void Publish(MqttNetLogLevel level, string source, string message, object[] parameters, Exception exception)
{
- var convertedLogLevel = ConvertLogLevel(logLevel);
+ var convertedLogLevel = ConvertLogLevel(level);
_logger.Log(convertedLogLevel, exception, message, parameters);
var logMessagePublishedEvent = LogMessagePublished;
if (logMessagePublishedEvent != null)
{
- var logMessage = new MqttNetLogMessage(null, DateTime.UtcNow, Thread.CurrentThread.ManagedThreadId, source, logLevel, message, exception);
+ var logMessage = new MqttNetLogMessage
+ {
+ Timestamp = DateTime.UtcNow,
+ ThreadId = Thread.CurrentThread.ManagedThreadId,
+ Source = source,
+ Level = level,
+ Message = message,
+ Exception = exception
+ };
+
logMessagePublishedEvent.Invoke(this, new MqttNetLogMessagePublishedEventArgs(logMessage));
}
}
-
- private static LogLevel ConvertLogLevel(MqttNetLogLevel logLevel)
+
+ public void Publish(MqttNetLogLevel logLevel, string message, object[] parameters, Exception exception)
+ {
+ Publish(logLevel, null, message, parameters, exception);
+ }
+
+ static LogLevel ConvertLogLevel(MqttNetLogLevel logLevel)
{
switch (logLevel)
{
diff --git a/Source/MQTTnet.Server/MQTTnet.Server.csproj b/Source/MQTTnet.Server/MQTTnet.Server.csproj
index 3f35d97..885ec2f 100644
--- a/Source/MQTTnet.Server/MQTTnet.Server.csproj
+++ b/Source/MQTTnet.Server/MQTTnet.Server.csproj
@@ -45,8 +45,10 @@
-
-
+
+
+
+
diff --git a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs
index 85c4176..9bcb42c 100644
--- a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs
+++ b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs
@@ -1,11 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.WebSockets;
-using System.Security.Authentication;
-using System.Text;
-using System.Threading.Tasks;
-using IronPython.Runtime;
+using IronPython.Runtime;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using MQTTnet.Adapter;
@@ -16,6 +9,13 @@ using MQTTnet.Protocol;
using MQTTnet.Server.Configuration;
using MQTTnet.Server.Scripting;
using MQTTnet.Server.Status;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.WebSockets;
+using System.Security.Authentication;
+using System.Text;
+using System.Threading.Tasks;
namespace MQTTnet.Server.Mqtt
{
@@ -65,11 +65,11 @@ namespace MQTTnet.Server.Mqtt
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
- _webSocketServerAdapter = new MqttWebSocketServerAdapter(mqttFactory.Logger.CreateChildLogger());
+ _webSocketServerAdapter = new MqttWebSocketServerAdapter(mqttFactory.Logger);
var adapters = new List
{
- new MqttTcpServerAdapter(mqttFactory.Logger.CreateChildLogger())
+ new MqttTcpServerAdapter(mqttFactory.Logger)
{
TreatSocketOpeningErrorAsWarning = true // Opening other ports than for HTTP is not allows in Azure App Services.
},
@@ -215,7 +215,7 @@ namespace MQTTnet.Server.Mqtt
options
.WithEncryptedEndpoint()
.WithEncryptionSslProtocol(SslProtocols.Tls12);
-
+
if (!string.IsNullOrEmpty(_settings.EncryptedTcpEndPoint?.Certificate?.Path))
{
IMqttServerCertificateCredentials certificateCredentials = null;
@@ -230,7 +230,7 @@ namespace MQTTnet.Server.Mqtt
options.WithEncryptionCertificate(_settings.EncryptedTcpEndPoint.Certificate.ReadCertificate(), certificateCredentials);
}
-
+
if (_settings.EncryptedTcpEndPoint.TryReadIPv4(out var address4))
{
options.WithEncryptedEndpointBoundIPAddress(address4);
diff --git a/Source/MQTTnet/Adapter/IMqttClientAdapterFactory.cs b/Source/MQTTnet/Adapter/IMqttClientAdapterFactory.cs
index cb0988d..c9aba6f 100644
--- a/Source/MQTTnet/Adapter/IMqttClientAdapterFactory.cs
+++ b/Source/MQTTnet/Adapter/IMqttClientAdapterFactory.cs
@@ -5,6 +5,6 @@ namespace MQTTnet.Adapter
{
public interface IMqttClientAdapterFactory
{
- IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger);
+ IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger);
}
}
diff --git a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs
index ccf5a33..e8bed00 100644
--- a/Source/MQTTnet/Adapter/MqttChannelAdapter.cs
+++ b/Source/MQTTnet/Adapter/MqttChannelAdapter.cs
@@ -14,12 +14,12 @@ using System.Threading.Tasks;
namespace MQTTnet.Adapter
{
- public class MqttChannelAdapter : Disposable, IMqttChannelAdapter
+ public sealed class MqttChannelAdapter : Disposable, IMqttChannelAdapter
{
const uint ErrorOperationAborted = 0x800703E3;
const int ReadBufferSize = 4096; // TODO: Move buffer size to config
- readonly IMqttNetChildLogger _logger;
+ readonly IMqttNetLogger _logger;
readonly IMqttChannel _channel;
readonly MqttPacketReader _packetReader;
@@ -30,7 +30,7 @@ namespace MQTTnet.Adapter
long _bytesReceived;
long _bytesSent;
- public MqttChannelAdapter(IMqttChannel channel, MqttPacketFormatterAdapter packetFormatterAdapter, IMqttNetChildLogger logger)
+ public MqttChannelAdapter(IMqttChannel channel, MqttPacketFormatterAdapter packetFormatterAdapter, IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
diff --git a/Source/MQTTnet/Client/MqttClient.cs b/Source/MQTTnet/Client/MqttClient.cs
index 29687fc..2546fc1 100644
--- a/Source/MQTTnet/Client/MqttClient.cs
+++ b/Source/MQTTnet/Client/MqttClient.cs
@@ -1,7 +1,3 @@
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
using MQTTnet.Adapter;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
@@ -17,6 +13,10 @@ using MQTTnet.Internal;
using MQTTnet.PacketDispatcher;
using MQTTnet.Packets;
using MQTTnet.Protocol;
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
namespace MQTTnet.Client
{
@@ -29,7 +29,7 @@ namespace MQTTnet.Client
private readonly object _disconnectLock = new object();
private readonly IMqttClientAdapterFactory _adapterFactory;
- private readonly IMqttNetChildLogger _logger;
+ private readonly IMqttNetLogger _logger;
private CancellationTokenSource _backgroundCancellationTokenSource;
private Task _packetReceiverTask;
diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
index 4fd0ccf..b301819 100644
--- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
+++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
@@ -1,19 +1,19 @@
-using System;
+using MQTTnet.Client.ExtendedAuthenticationExchange;
+using MQTTnet.Formatter;
+using System;
using System.Linq;
using System.Text;
-using MQTTnet.Client.ExtendedAuthenticationExchange;
-using MQTTnet.Formatter;
namespace MQTTnet.Client.Options
{
public class MqttClientOptionsBuilder
{
- private readonly MqttClientOptions _options = new MqttClientOptions();
+ readonly MqttClientOptions _options = new MqttClientOptions();
- private MqttClientTcpOptions _tcpOptions;
- private MqttClientWebSocketOptions _webSocketOptions;
- private MqttClientOptionsBuilderTlsParameters _tlsParameters;
- private MqttClientWebSocketProxyOptions _proxyOptions;
+ MqttClientTcpOptions _tcpOptions;
+ MqttClientWebSocketOptions _webSocketOptions;
+ MqttClientOptionsBuilderTlsParameters _tlsParameters;
+ MqttClientWebSocketProxyOptions _proxyOptions;
public MqttClientOptionsBuilder WithProtocolVersion(MqttProtocolVersion value)
{
diff --git a/Source/MQTTnet/Diagnostics/IMqttNetChildLogger.cs b/Source/MQTTnet/Diagnostics/IMqttNetChildLogger.cs
deleted file mode 100644
index df99f44..0000000
--- a/Source/MQTTnet/Diagnostics/IMqttNetChildLogger.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace MQTTnet.Diagnostics
-{
- public interface IMqttNetChildLogger
- {
- IMqttNetChildLogger CreateChildLogger(string source = null);
-
- 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);
- }
-}
diff --git a/Source/MQTTnet/Diagnostics/IMqttNetLogger.cs b/Source/MQTTnet/Diagnostics/IMqttNetLogger.cs
index 73b6fcb..b952cf5 100644
--- a/Source/MQTTnet/Diagnostics/IMqttNetLogger.cs
+++ b/Source/MQTTnet/Diagnostics/IMqttNetLogger.cs
@@ -6,8 +6,8 @@ namespace MQTTnet.Diagnostics
{
event EventHandler LogMessagePublished;
- IMqttNetChildLogger CreateChildLogger(string source = null);
+ IMqttNetLogger CreateChildLogger(string source);
- void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception);
+ void Publish(MqttNetLogLevel logLevel, string message, object[] parameters, Exception exception);
}
}
diff --git a/Source/MQTTnet/Diagnostics/MqttNetChildLogger.cs b/Source/MQTTnet/Diagnostics/MqttNetChildLogger.cs
deleted file mode 100644
index 3733454..0000000
--- a/Source/MQTTnet/Diagnostics/MqttNetChildLogger.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-
-namespace MQTTnet.Diagnostics
-{
- public class MqttNetChildLogger : IMqttNetChildLogger
- {
- private readonly IMqttNetLogger _logger;
- private readonly string _source;
-
- public MqttNetChildLogger(IMqttNetLogger logger, string source)
- {
- _logger = logger ?? throw new ArgumentNullException(nameof(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);
- }
- }
-}
diff --git a/Source/MQTTnet/Diagnostics/MqttNetLogMessage.cs b/Source/MQTTnet/Diagnostics/MqttNetLogMessage.cs
index 107d8f3..1ab1b4c 100644
--- a/Source/MQTTnet/Diagnostics/MqttNetLogMessage.cs
+++ b/Source/MQTTnet/Diagnostics/MqttNetLogMessage.cs
@@ -4,30 +4,19 @@ namespace MQTTnet.Diagnostics
{
public class MqttNetLogMessage
{
- public MqttNetLogMessage(string logId, DateTime timestamp, int threadId, string source, MqttNetLogLevel level, string message, Exception exception)
- {
- LogId = logId;
- Timestamp = timestamp;
- ThreadId = threadId;
- Source = source;
- Level = level;
- Message = message;
- Exception = exception;
- }
-
- public string LogId { get; }
+ public string LogId { get; set; }
- public DateTime Timestamp { get; }
+ public DateTime Timestamp { get; set; }
- public int ThreadId { get; }
+ public int ThreadId { get; set; }
- public string Source { get; }
+ public string Source { get; set; }
- public MqttNetLogLevel Level { get; }
+ public MqttNetLogLevel Level { get; set; }
- public string Message { get; }
+ public string Message { get; set; }
- public Exception Exception { get; }
+ public Exception Exception { get; set; }
public override string ToString()
{
diff --git a/Source/MQTTnet/Diagnostics/MqttNetLogMessagePublishedEventArgs.cs b/Source/MQTTnet/Diagnostics/MqttNetLogMessagePublishedEventArgs.cs
index 8a0c0fc..e64a40d 100644
--- a/Source/MQTTnet/Diagnostics/MqttNetLogMessagePublishedEventArgs.cs
+++ b/Source/MQTTnet/Diagnostics/MqttNetLogMessagePublishedEventArgs.cs
@@ -6,9 +6,14 @@ namespace MQTTnet.Diagnostics
{
public MqttNetLogMessagePublishedEventArgs(MqttNetLogMessage logMessage)
{
+ LogMessage = logMessage ?? throw new ArgumentNullException(nameof(logMessage));
+
TraceMessage = logMessage ?? throw new ArgumentNullException(nameof(logMessage));
}
+ [Obsolete("Use new proeprty LogMessage instead.")]
public MqttNetLogMessage TraceMessage { get; }
+
+ public MqttNetLogMessage LogMessage { get; }
}
}
diff --git a/Source/MQTTnet/Diagnostics/MqttNetLogger.cs b/Source/MQTTnet/Diagnostics/MqttNetLogger.cs
index 56a664e..bfd4c42 100644
--- a/Source/MQTTnet/Diagnostics/MqttNetLogger.cs
+++ b/Source/MQTTnet/Diagnostics/MqttNetLogger.cs
@@ -4,26 +4,51 @@ namespace MQTTnet.Diagnostics
{
public class MqttNetLogger : IMqttNetLogger
{
- private readonly string _logId;
+ readonly string _logId;
+ readonly string _source;
- public MqttNetLogger(string logId = null)
+ readonly MqttNetLogger _parentLogger;
+
+ public MqttNetLogger(string source, string logId)
+ {
+ _source = source;
+ _logId = logId;
+ }
+
+ public MqttNetLogger()
+ {
+ }
+
+ public MqttNetLogger(string logId)
+ {
+ _logId = logId;
+ }
+
+ MqttNetLogger(MqttNetLogger parentLogger, string logId, string source)
{
+ _parentLogger = parentLogger ?? throw new ArgumentNullException(nameof(parentLogger));
+ _source = source ?? throw new ArgumentNullException(nameof(source));
+
_logId = logId;
}
public event EventHandler LogMessagePublished;
- public IMqttNetChildLogger CreateChildLogger(string source = null)
+ // TODO: Consider creating a LoggerFactory which will allow creating loggers. The logger factory will
+ // be the only place which has the published event.
+ public IMqttNetLogger CreateChildLogger(string source)
{
- return new MqttNetChildLogger(this, source);
+ if (source is null) throw new ArgumentNullException(nameof(source));
+
+ return new MqttNetLogger(this, _logId, source);
}
- public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
+ public void Publish(MqttNetLogLevel level, string message, object[] parameters, Exception exception)
{
var hasLocalListeners = LogMessagePublished != null;
var hasGlobalListeners = MqttNetGlobalLogger.HasListeners;
- if (!hasLocalListeners && !hasGlobalListeners)
+ if (!hasLocalListeners && !hasGlobalListeners && _parentLogger == null)
{
return;
}
@@ -40,17 +65,35 @@ namespace MQTTnet.Diagnostics
}
}
- var traceMessage = new MqttNetLogMessage(_logId, DateTime.UtcNow, Environment.CurrentManagedThreadId, source, logLevel, message, exception);
+ var logMessage = new MqttNetLogMessage
+ {
+ LogId = _logId,
+ Timestamp = DateTime.UtcNow,
+ Source = _source,
+ ThreadId = Environment.CurrentManagedThreadId,
+ Level = level,
+ Message = message,
+ Exception = exception
+ };
if (hasGlobalListeners)
{
- MqttNetGlobalLogger.Publish(traceMessage);
+ MqttNetGlobalLogger.Publish(logMessage);
}
if (hasLocalListeners)
{
- LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(traceMessage));
+ LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(logMessage));
}
+
+ _parentLogger?.Publish(logMessage);
+ }
+
+ void Publish(MqttNetLogMessage logMessage)
+ {
+ LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(logMessage));
+
+ _parentLogger?.Publish(logMessage);
}
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet/Diagnostics/MqttNetLoggerExtensions.cs b/Source/MQTTnet/Diagnostics/MqttNetLoggerExtensions.cs
new file mode 100644
index 0000000..bc8a97b
--- /dev/null
+++ b/Source/MQTTnet/Diagnostics/MqttNetLoggerExtensions.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace MQTTnet.Diagnostics
+{
+ public static class MqttNetLoggerExtensions
+ {
+ public static void Verbose(this IMqttNetLogger logger, string message, params object[] parameters)
+ {
+ if (logger is null) throw new ArgumentNullException(nameof(logger));
+
+ logger.Publish(MqttNetLogLevel.Verbose, message, parameters, null);
+ }
+
+ public static void Info(this IMqttNetLogger logger, string message, params object[] parameters)
+ {
+ if (logger is null) throw new ArgumentNullException(nameof(logger));
+
+ logger.Publish(MqttNetLogLevel.Info, message, parameters, null);
+ }
+
+ public static void Warning(this IMqttNetLogger logger, Exception exception, string message, params object[] parameters)
+ {
+ if (logger is null) throw new ArgumentNullException(nameof(logger));
+
+ logger.Publish(MqttNetLogLevel.Warning, message, parameters, exception);
+ }
+
+ public static void Error(this IMqttNetLogger logger, Exception exception, string message, params object[] parameters)
+ {
+ if (logger is null) throw new ArgumentNullException(nameof(logger));
+
+ logger.Publish(MqttNetLogLevel.Error, message, parameters, exception);
+ }
+ }
+}
diff --git a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs b/Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
similarity index 89%
rename from Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs
rename to Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
index efbf08b..7135af6 100644
--- a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs
+++ b/Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
@@ -1,6 +1,6 @@
namespace MQTTnet.Diagnostics
{
- public static class TargetFrameworkInfoProvider
+ public static class TargetFrameworkProvider
{
public static string TargetFramework
{
diff --git a/Source/MQTTnet/Extensions/MqttClientOptionsBuilderExtension.cs b/Source/MQTTnet/Extensions/MqttClientOptionsBuilderExtension.cs
new file mode 100644
index 0000000..fc9da23
--- /dev/null
+++ b/Source/MQTTnet/Extensions/MqttClientOptionsBuilderExtension.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Linq;
+using MQTTnet.Client.Options;
+
+namespace MQTTnet.Extensions
+{
+ public static class MqttClientOptionsBuilderExtension
+ {
+ public static MqttClientOptionsBuilder WithConnectionUri(this MqttClientOptionsBuilder builder, Uri uri)
+ {
+ var port = uri.IsDefaultPort ? null : (int?) uri.Port;
+ switch (uri.Scheme.ToLower())
+ {
+ case "tcp":
+ case "mqtt":
+ builder.WithTcpServer(uri.Host, port);
+ break;
+
+ case "mqtts":
+ builder.WithTcpServer(uri.Host, port).WithTls();
+ break;
+
+ case "ws":
+ case "wss":
+ builder.WithWebSocketServer(uri.ToString());
+ break;
+
+ default:
+ throw new ArgumentException("Unexpected scheme in uri.");
+ }
+
+ if (!string.IsNullOrEmpty(uri.UserInfo))
+ {
+ var userInfo = uri.UserInfo.Split(':');
+ var username = userInfo[0];
+ var password = userInfo.Length > 1 ? userInfo[1] : "";
+ builder.WithCredentials(username, password);
+ }
+
+ return builder;
+ }
+
+ public static MqttClientOptionsBuilder WithConnectionUri(this MqttClientOptionsBuilder builder, string uri)
+ {
+ return WithConnectionUri(builder, new Uri(uri, UriKind.Absolute));
+ }
+ }
+}
diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs
new file mode 100644
index 0000000..f861c32
--- /dev/null
+++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Linq;
+
+namespace MQTTnet.Extensions
+{
+ public static class UserPropertyExtension
+ {
+ public static string GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.Ordinal)
+ {
+ if (message == null) throw new ArgumentNullException(nameof(message));
+ if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
+
+ return message.UserProperties?.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value;
+ }
+ }
+}
diff --git a/Source/MQTTnet/Formatter/V3/MqttV310DataConverter.cs b/Source/MQTTnet/Formatter/V3/MqttV310DataConverter.cs
index 48d42cd..4bf4944 100644
--- a/Source/MQTTnet/Formatter/V3/MqttV310DataConverter.cs
+++ b/Source/MQTTnet/Formatter/V3/MqttV310DataConverter.cs
@@ -20,11 +20,6 @@ namespace MQTTnet.Formatter.V3
{
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
- if (applicationMessage.UserProperties?.Any() == true)
- {
- throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
- }
-
return new MqttPublishPacket
{
Topic = applicationMessage.Topic,
@@ -171,11 +166,6 @@ namespace MQTTnet.Formatter.V3
{
if (options == null) throw new ArgumentNullException(nameof(options));
- if (options.UserProperties?.Any() == true)
- {
- throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
- }
-
var subscribePacket = new MqttSubscribePacket();
subscribePacket.TopicFilters.AddRange(options.TopicFilters);
@@ -186,11 +176,6 @@ namespace MQTTnet.Formatter.V3
{
if (options == null) throw new ArgumentNullException(nameof(options));
- if (options.UserProperties?.Any() == true)
- {
- throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
- }
-
var unsubscribePacket = new MqttUnsubscribePacket();
unsubscribePacket.TopicFilters.AddRange(options.TopicFilters);
diff --git a/Source/MQTTnet/Implementations/CrossPlatformSocket.cs b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs
new file mode 100644
index 0000000..4d7f6c9
--- /dev/null
+++ b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs
@@ -0,0 +1,229 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MQTTnet.Implementations
+{
+ public sealed class CrossPlatformSocket : IDisposable
+ {
+ readonly Socket _socket;
+
+ public CrossPlatformSocket(AddressFamily addressFamily)
+ {
+ _socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
+ }
+
+ public CrossPlatformSocket()
+ {
+ // Having this contructor is important because avoiding the address family as parameter
+ // will make use of dual mode in the .net framework.
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ }
+
+ public CrossPlatformSocket(Socket socket)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ }
+
+ public bool NoDelay
+ {
+ get
+ {
+ return (int)_socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) > 0;
+ }
+
+ set
+ {
+ _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0);
+ }
+ }
+
+ public bool DualMode
+ {
+ get
+ {
+ return _socket.DualMode;
+ }
+
+ set
+ {
+ _socket.DualMode = value;
+ }
+ }
+
+ public int ReceiveBufferSize
+ {
+ get
+ {
+ return _socket.ReceiveBufferSize;
+ }
+
+ set
+ {
+ _socket.ReceiveBufferSize = value;
+ }
+ }
+
+ public int SendBufferSize
+ {
+ get
+ {
+ return _socket.SendBufferSize;
+ }
+
+ set
+ {
+ _socket.SendBufferSize = value;
+ }
+ }
+
+ public EndPoint RemoteEndPoint
+ {
+ get
+ {
+ return _socket.RemoteEndPoint;
+ }
+ }
+
+ public bool ReuseAddress
+ {
+ get
+ {
+ return (int)_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress) != 0;
+ }
+
+ set
+ {
+ _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, value ? 1 : 0);
+ }
+ }
+
+ public async Task AcceptAsync()
+ {
+ try
+ {
+#if NET452 || NET461
+ var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false);
+ return new CrossPlatformSocket(clientSocket);
+#else
+ var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false);
+ return new CrossPlatformSocket(clientSocket);
+#endif
+ }
+ catch (ObjectDisposedException)
+ {
+ // This will happen when _socket.EndAccept gets called by Task library but the socket is already disposed.
+ return null;
+ }
+ }
+
+ public void Bind(EndPoint localEndPoint)
+ {
+ if (localEndPoint is null) throw new ArgumentNullException(nameof(localEndPoint));
+
+ _socket.Bind(localEndPoint);
+ }
+
+ public void Listen(int connectionBacklog)
+ {
+ _socket.Listen(connectionBacklog);
+ }
+
+ public async Task ConnectAsync(string host, int port, CancellationToken cancellationToken)
+ {
+ if (host is null) throw new ArgumentNullException(nameof(host));
+
+ try
+ {
+ // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
+ using (cancellationToken.Register(() => _socket.Dispose()))
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+#if NET452 || NET461
+ await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, host, port, null).ConfigureAwait(false);
+#else
+ await _socket.ConnectAsync(host, port).ConfigureAwait(false);
+#endif
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ // This will happen when _socket.EndConnect gets called by Task library but the socket is already disposed.
+ }
+ }
+
+ public async Task SendAsync(ArraySegment buffer, SocketFlags socketFlags)
+ {
+ try
+ {
+#if NET452 || NET461
+ await Task.Factory.FromAsync(SocketWrapper.BeginSend, _socket.EndSend, new SocketWrapper(_socket, buffer, socketFlags)).ConfigureAwait(false);
+#else
+ await _socket.SendAsync(buffer, socketFlags).ConfigureAwait(false);
+#endif
+ }
+ catch (ObjectDisposedException)
+ {
+ // This will happen when _socket.EndConnect gets called by Task library but the socket is already disposed.
+ }
+ }
+
+ public async Task ReceiveAsync(ArraySegment buffer, SocketFlags socketFlags)
+ {
+ try
+ {
+#if NET452 || NET461
+ return await Task.Factory.FromAsync(SocketWrapper.BeginReceive, _socket.EndReceive, new SocketWrapper(_socket, buffer, socketFlags)).ConfigureAwait(false);
+#else
+ return await _socket.ReceiveAsync(buffer, socketFlags).ConfigureAwait(false);
+#endif
+ }
+ catch (ObjectDisposedException)
+ {
+ // This will happen when _socket.EndReceive gets called by Task library but the socket is already disposed.
+ return -1;
+ }
+ }
+
+ public NetworkStream GetStream()
+ {
+ return new NetworkStream(_socket, true);
+ }
+
+ public void Dispose()
+ {
+ _socket?.Dispose();
+ }
+
+#if NET452 || NET461
+ class SocketWrapper
+ {
+ readonly Socket _socket;
+ readonly ArraySegment _buffer;
+ readonly SocketFlags _socketFlags;
+
+ public SocketWrapper(Socket socket, ArraySegment buffer, SocketFlags socketFlags)
+ {
+ _socket = socket;
+ _buffer = buffer;
+ _socketFlags = socketFlags;
+ }
+
+ public static IAsyncResult BeginSend(AsyncCallback callback, object state)
+ {
+ var socketWrapper = (SocketWrapper)state;
+ return socketWrapper._socket.BeginSend(socketWrapper._buffer.Array, socketWrapper._buffer.Offset, socketWrapper._buffer.Count, socketWrapper._socketFlags, callback, state);
+ }
+
+ public static IAsyncResult BeginReceive(AsyncCallback callback, object state)
+ {
+ var socketWrapper = (SocketWrapper)state;
+ return socketWrapper._socket.BeginReceive(socketWrapper._buffer.Array, socketWrapper._buffer.Offset, socketWrapper._buffer.Count, socketWrapper._socketFlags, callback, state);
+ }
+ }
+#endif
+ }
+}
diff --git a/Source/MQTTnet/Implementations/MqttClientAdapterFactory.cs b/Source/MQTTnet/Implementations/MqttClientAdapterFactory.cs
index 2377cde..148fe04 100644
--- a/Source/MQTTnet/Implementations/MqttClientAdapterFactory.cs
+++ b/Source/MQTTnet/Implementations/MqttClientAdapterFactory.cs
@@ -1,17 +1,17 @@
-using System;
-using MQTTnet.Adapter;
+using MQTTnet.Adapter;
using MQTTnet.Client.Options;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
+using System;
namespace MQTTnet.Implementations
{
public class MqttClientAdapterFactory : IMqttClientAdapterFactory
{
- public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
+ public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
-
+
switch (options.ChannelOptions)
{
case MqttClientTcpOptions _:
diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
index 71050e1..021a7d4 100644
--- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
@@ -46,15 +46,15 @@ namespace MQTTnet.Implementations
public async Task ConnectAsync(CancellationToken cancellationToken)
{
- Socket socket;
+ CrossPlatformSocket socket;
if (_options.AddressFamily == AddressFamily.Unspecified)
{
- socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ socket = new CrossPlatformSocket();
}
else
{
- socket = new Socket(_options.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ socket = new CrossPlatformSocket(_options.AddressFamily);
}
socket.ReceiveBufferSize = _options.BufferSize;
@@ -69,20 +69,24 @@ namespace MQTTnet.Implementations
socket.DualMode = _options.DualMode.Value;
}
- // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
- using (cancellationToken.Register(() => socket.Dispose()))
- {
- await PlatformAbstractionLayer.ConnectAsync(socket, _options.Server, _options.GetPort()).ConfigureAwait(false);
- }
+ await socket.ConnectAsync(_options.Server, _options.GetPort(), cancellationToken).ConfigureAwait(false);
- var networkStream = new NetworkStream(socket, true);
+ var networkStream = socket.GetStream();
if (_options.TlsOptions.UseTls)
{
var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
- _stream = sslStream;
+ try
+ {
+ await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
+ }
+ catch
+ {
+ sslStream.Dispose();
+ throw;
+ }
- await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
+ _stream = sslStream;
}
else
{
@@ -107,17 +111,14 @@ namespace MQTTnet.Implementations
// Workaround for: https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(Dispose))
{
- if (cancellationToken.IsCancellationRequested)
- {
- return 0;
- }
+ cancellationToken.ThrowIfCancellationRequested();
return await _stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
}
}
catch (ObjectDisposedException)
{
- return 0;
+ return -1;
}
catch (IOException exception)
{
@@ -139,10 +140,7 @@ namespace MQTTnet.Implementations
// Workaround for: https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(Dispose))
{
- if (cancellationToken.IsCancellationRequested)
- {
- return;
- }
+ cancellationToken.ThrowIfCancellationRequested();
await _stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
}
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
index 3b24bd1..4d26da7 100644
--- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
@@ -11,14 +11,14 @@ using System.Threading.Tasks;
namespace MQTTnet.Implementations
{
- public class MqttTcpServerAdapter : IMqttServerAdapter
+ public sealed class MqttTcpServerAdapter : IMqttServerAdapter
{
- private readonly IMqttNetChildLogger _logger;
+ readonly IMqttNetLogger _logger;
- private IMqttServerOptions _options;
- private StreamSocketListener _listener;
+ IMqttServerOptions _options;
+ StreamSocketListener _listener;
- public MqttTcpServerAdapter(IMqttNetChildLogger logger)
+ public MqttTcpServerAdapter(IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -68,7 +68,7 @@ namespace MQTTnet.Implementations
_listener = null;
}
- private async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
+ async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
index 501c4da..22a5824 100644
--- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
@@ -1,4 +1,8 @@
#if !WINDOWS_UWP
+using MQTTnet.Adapter;
+using MQTTnet.Diagnostics;
+using MQTTnet.Internal;
+using MQTTnet.Server;
using System;
using System.Collections.Generic;
using System.Net;
@@ -6,21 +10,17 @@ using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
-using MQTTnet.Adapter;
-using MQTTnet.Diagnostics;
-using MQTTnet.Internal;
-using MQTTnet.Server;
namespace MQTTnet.Implementations
{
- public class MqttTcpServerAdapter : Disposable, IMqttServerAdapter
+ public sealed class MqttTcpServerAdapter : Disposable, IMqttServerAdapter
{
- private readonly List _listeners = new List();
- private readonly IMqttNetChildLogger _logger;
+ readonly List _listeners = new List();
+ readonly IMqttNetLogger _logger;
- private CancellationTokenSource _cancellationTokenSource;
+ CancellationTokenSource _cancellationTokenSource;
- public MqttTcpServerAdapter(IMqttNetChildLogger logger)
+ public MqttTcpServerAdapter(IMqttNetLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
@@ -59,7 +59,7 @@ namespace MQTTnet.Implementations
{
tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate, options.TlsEndpointOptions.CertificateCredentials.Password);
}
-
+
if (!tlsCertificate.HasPrivateKey)
{
throw new InvalidOperationException("The certificate for TLS encryption must contain the private key.");
@@ -77,7 +77,17 @@ namespace MQTTnet.Implementations
return Task.FromResult(0);
}
- private void Cleanup()
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Cleanup();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ void Cleanup()
{
_cancellationTokenSource?.Cancel(false);
_cancellationTokenSource?.Dispose();
@@ -91,16 +101,7 @@ namespace MQTTnet.Implementations
_listeners.Clear();
}
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Cleanup();
- }
- base.Dispose(disposing);
- }
-
- private void RegisterListeners(MqttServerTcpEndpointBaseOptions options, X509Certificate2 tlsCertificate, CancellationToken cancellationToken)
+ void RegisterListeners(MqttServerTcpEndpointBaseOptions options, X509Certificate2 tlsCertificate, CancellationToken cancellationToken)
{
if (!options.BoundInterNetworkAddress.Equals(IPAddress.None))
{
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
index f2f439e..83ef80f 100644
--- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
@@ -1,4 +1,9 @@
#if !WINDOWS_UWP
+using MQTTnet.Adapter;
+using MQTTnet.Diagnostics;
+using MQTTnet.Formatter;
+using MQTTnet.Internal;
+using MQTTnet.Server;
using System;
using System.IO;
using System.Net;
@@ -7,30 +12,25 @@ using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
-using MQTTnet.Adapter;
-using MQTTnet.Diagnostics;
-using MQTTnet.Formatter;
-using MQTTnet.Internal;
-using MQTTnet.Server;
namespace MQTTnet.Implementations
{
- public class MqttTcpServerListener : IDisposable
+ public sealed class MqttTcpServerListener : IDisposable
{
- private readonly IMqttNetChildLogger _logger;
- private readonly AddressFamily _addressFamily;
- private readonly MqttServerTcpEndpointBaseOptions _options;
- private readonly MqttServerTlsTcpEndpointOptions _tlsOptions;
- private readonly X509Certificate2 _tlsCertificate;
+ readonly IMqttNetLogger _logger;
+ readonly AddressFamily _addressFamily;
+ readonly MqttServerTcpEndpointBaseOptions _options;
+ readonly MqttServerTlsTcpEndpointOptions _tlsOptions;
+ readonly X509Certificate2 _tlsCertificate;
- private Socket _socket;
+ private CrossPlatformSocket _socket;
private IPEndPoint _localEndPoint;
public MqttTcpServerListener(
AddressFamily addressFamily,
MqttServerTcpEndpointBaseOptions options,
X509Certificate2 tlsCertificate,
- IMqttNetChildLogger logger)
+ IMqttNetLogger logger)
{
_addressFamily = addressFamily;
_options = options;
@@ -59,20 +59,20 @@ namespace MQTTnet.Implementations
_logger.Info($"Starting TCP listener for {_localEndPoint} TLS={_tlsCertificate != null}.");
- _socket = new Socket(_addressFamily, SocketType.Stream, ProtocolType.Tcp);
+ _socket = new CrossPlatformSocket(_addressFamily);
// Usage of socket options is described here: https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.setsocketoption?view=netcore-2.2
if (_options.ReuseAddress)
{
- _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _socket.ReuseAddress = true;
}
-
+
if (_options.NoDelay)
{
- _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
+ _socket.NoDelay = true;
}
-
+
_socket.Bind(_localEndPoint);
_socket.Listen(_options.ConnectionBacklog);
@@ -87,7 +87,7 @@ namespace MQTTnet.Implementations
throw;
}
- _logger.Warning(exception,"Error while creating listener socket for local end point '{0}'.", _localEndPoint);
+ _logger.Warning(exception, "Error while creating listener socket for local end point '{0}'.", _localEndPoint);
return false;
}
}
@@ -101,13 +101,13 @@ namespace MQTTnet.Implementations
#endif
}
- private async Task AcceptClientConnectionsAsync(CancellationToken cancellationToken)
+ async Task AcceptClientConnectionsAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
- var clientSocket = await PlatformAbstractionLayer.AcceptAsync(_socket).ConfigureAwait(false);
+ var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false);
if (clientSocket == null)
{
continue;
@@ -116,7 +116,7 @@ namespace MQTTnet.Implementations
Task.Run(() => TryHandleClientConnectionAsync(clientSocket), cancellationToken).Forget(_logger);
}
catch (OperationCanceledException)
- {
+ {
}
catch (Exception exception)
{
@@ -128,14 +128,14 @@ namespace MQTTnet.Implementations
continue;
}
}
-
+
_logger.Error(exception, $"Error while accepting connection at TCP listener {_localEndPoint} TLS={_tlsCertificate != null}.");
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
}
}
}
- private async Task TryHandleClientConnectionAsync(Socket clientSocket)
+ async Task TryHandleClientConnectionAsync(CrossPlatformSocket clientSocket)
{
Stream stream = null;
string remoteEndPoint = null;
@@ -151,7 +151,7 @@ namespace MQTTnet.Implementations
clientSocket.NoDelay = _options.NoDelay;
- stream = new NetworkStream(clientSocket, true);
+ stream = clientSocket.GetStream();
X509Certificate2 clientCertificate = null;
@@ -160,9 +160,9 @@ namespace MQTTnet.Implementations
var sslStream = new SslStream(stream, false, _tlsOptions.RemoteCertificateValidationCallback);
await sslStream.AuthenticateAsServerAsync(
- _tlsCertificate,
- _tlsOptions.ClientCertificateRequired,
- _tlsOptions.SslProtocol,
+ _tlsCertificate,
+ _tlsOptions.ClientCertificateRequired,
+ _tlsOptions.SslProtocol,
_tlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
stream = sslStream;
diff --git a/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs b/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs
index 80c0890..0b683dc 100644
--- a/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs
+++ b/Source/MQTTnet/Implementations/PlatformAbstractionLayer.cs
@@ -1,94 +1,9 @@
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
namespace MQTTnet.Implementations
{
public static class PlatformAbstractionLayer
{
- // TODO: Consider creating primitives like "MqttNetSocket" which will wrap all required methods and do the platform stuff.
- public static async Task AcceptAsync(Socket socket)
- {
-#if NET452 || NET461
- try
- {
- return await Task.Factory.FromAsync(socket.BeginAccept, socket.EndAccept, null).ConfigureAwait(false);
- }
- catch (ObjectDisposedException)
- {
- return null;
- }
-#else
- return await socket.AcceptAsync().ConfigureAwait(false);
-#endif
- }
-
-
- public static Task ConnectAsync(Socket socket, IPAddress ip, int port)
- {
-#if NET452 || NET461
- return Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, ip, port, null);
-#else
- return socket.ConnectAsync(ip, port);
-#endif
- }
-
- public static Task ConnectAsync(Socket socket, string host, int port)
- {
-#if NET452 || NET461
- return Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, host, port, null);
-#else
- return socket.ConnectAsync(host, port);
-#endif
- }
-
-#if NET452 || NET461
- public class SocketWrapper
- {
- private readonly Socket _socket;
- private readonly ArraySegment _buffer;
- private readonly SocketFlags _socketFlags;
-
- public SocketWrapper(Socket socket, ArraySegment buffer, SocketFlags socketFlags)
- {
- _socket = socket;
- _buffer = buffer;
- _socketFlags = socketFlags;
- }
-
- public static IAsyncResult BeginSend(AsyncCallback callback, object state)
- {
- var real = (SocketWrapper)state;
- return real._socket.BeginSend(real._buffer.Array, real._buffer.Offset, real._buffer.Count, real._socketFlags, callback, state);
- }
-
- public static IAsyncResult BeginReceive(AsyncCallback callback, object state)
- {
- var real = (SocketWrapper)state;
- return real._socket.BeginReceive(real._buffer.Array, real._buffer.Offset, real._buffer.Count, real._socketFlags, callback, state);
- }
- }
-#endif
-
- public static Task SendAsync(Socket socket, ArraySegment buffer, SocketFlags socketFlags)
- {
-#if NET452 || NET461
- return Task.Factory.FromAsync(SocketWrapper.BeginSend, socket.EndSend, new SocketWrapper(socket, buffer, socketFlags));
-#else
- return socket.SendAsync(buffer, socketFlags);
-#endif
- }
-
- public static Task ReceiveAsync(Socket socket, ArraySegment buffer, SocketFlags socketFlags)
- {
-#if NET452 || NET461
- return Task.Factory.FromAsync(SocketWrapper.BeginReceive, socket.EndReceive, new SocketWrapper(socket, buffer, socketFlags));
-#else
- return socket.ReceiveAsync(buffer, socketFlags);
-#endif
- }
-
public static Task CompletedTask
{
get
diff --git a/Source/MQTTnet/Internal/TaskExtensions.cs b/Source/MQTTnet/Internal/TaskExtensions.cs
index 733631c..12a8c07 100644
--- a/Source/MQTTnet/Internal/TaskExtensions.cs
+++ b/Source/MQTTnet/Internal/TaskExtensions.cs
@@ -1,11 +1,11 @@
-using System.Threading.Tasks;
-using MQTTnet.Diagnostics;
+using MQTTnet.Diagnostics;
+using System.Threading.Tasks;
namespace MQTTnet.Internal
{
public static class TaskExtensions
{
- public static void Forget(this Task task, IMqttNetChildLogger logger)
+ public static void Forget(this Task task, IMqttNetLogger logger)
{
task?.ContinueWith(t =>
{
diff --git a/Source/MQTTnet/LowLevelClient/ILowLevelMqttClient.cs b/Source/MQTTnet/LowLevelClient/ILowLevelMqttClient.cs
new file mode 100644
index 0000000..1734bf4
--- /dev/null
+++ b/Source/MQTTnet/LowLevelClient/ILowLevelMqttClient.cs
@@ -0,0 +1,19 @@
+using MQTTnet.Client.Options;
+using MQTTnet.Packets;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MQTTnet.LowLevelClient
+{
+ public interface ILowLevelMqttClient : IDisposable
+ {
+ Task ConnectAsync(IMqttClientOptions options, CancellationToken cancellationToken);
+
+ Task DisconnectAsync(CancellationToken cancellationToken);
+
+ Task SendAsync(MqttBasePacket packet, CancellationToken cancellationToken);
+
+ Task ReceiveAsync(CancellationToken cancellationToken);
+ }
+}
diff --git a/Source/MQTTnet/LowLevelClient/LowLevelMqttClient.cs b/Source/MQTTnet/LowLevelClient/LowLevelMqttClient.cs
new file mode 100644
index 0000000..045100d
--- /dev/null
+++ b/Source/MQTTnet/LowLevelClient/LowLevelMqttClient.cs
@@ -0,0 +1,128 @@
+using MQTTnet.Adapter;
+using MQTTnet.Client.Options;
+using MQTTnet.Diagnostics;
+using MQTTnet.Packets;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MQTTnet.LowLevelClient
+{
+ public sealed class LowLevelMqttClient : ILowLevelMqttClient
+ {
+ readonly IMqttNetLogger _logger;
+ readonly IMqttClientAdapterFactory _clientAdapterFactory;
+
+ IMqttChannelAdapter _adapter;
+ IMqttClientOptions _options;
+
+ public LowLevelMqttClient(IMqttClientAdapterFactory clientAdapterFactory, IMqttNetLogger logger)
+ {
+ if (clientAdapterFactory is null) throw new ArgumentNullException(nameof(clientAdapterFactory));
+ if (logger is null) throw new ArgumentNullException(nameof(logger));
+
+ _clientAdapterFactory = clientAdapterFactory;
+ _logger = logger.CreateChildLogger(nameof(LowLevelMqttClient));
+ }
+
+ bool IsConnected => _adapter != null;
+
+ public async Task ConnectAsync(IMqttClientOptions options, CancellationToken cancellationToken)
+ {
+ if (options is null) throw new ArgumentNullException(nameof(options));
+
+ if (_adapter != null)
+ {
+ throw new InvalidOperationException("Low level MQTT client is already connected. Disconnect first before connecting again.");
+ }
+
+ var newAdapter = _clientAdapterFactory.CreateClientAdapter(options, _logger);
+
+ try
+ {
+ _logger.Verbose($"Trying to connect with server '{options.ChannelOptions}' (Timeout={options.CommunicationTimeout}).");
+ await newAdapter.ConnectAsync(options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
+ _logger.Verbose("Connection with server established.");
+
+ _options = options;
+ }
+ catch (Exception)
+ {
+ _adapter.Dispose();
+ throw;
+ }
+
+ _adapter = newAdapter;
+ }
+
+ public async Task DisconnectAsync(CancellationToken cancellationToken)
+ {
+ if (_adapter == null)
+ {
+ return;
+ }
+
+ await SafeDisconnect(cancellationToken).ConfigureAwait(false);
+ _adapter = null;
+ }
+
+ public async Task SendAsync(MqttBasePacket packet, CancellationToken cancellationToken)
+ {
+ if (packet is null) throw new ArgumentNullException(nameof(packet));
+
+ if (_adapter == null)
+ {
+ throw new InvalidOperationException("Low level MQTT client is not connected.");
+ }
+
+ try
+ {
+ await _adapter.SendPacketAsync(packet, _options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception)
+ {
+ await SafeDisconnect(cancellationToken).ConfigureAwait(false);
+ throw;
+ }
+ }
+
+ public async Task ReceiveAsync(CancellationToken cancellationToken)
+ {
+ if (_adapter == null)
+ {
+ throw new InvalidOperationException("Low level MQTT client is not connected.");
+ }
+
+ try
+ {
+ return await _adapter.ReceivePacketAsync(_options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception)
+ {
+ await SafeDisconnect(cancellationToken).ConfigureAwait(false);
+ throw;
+ }
+ }
+
+ public void Dispose()
+ {
+ _adapter?.Dispose();
+ }
+
+ async Task SafeDisconnect(CancellationToken cancellationToken)
+ {
+ try
+ {
+ await _adapter.DisconnectAsync(_options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception exception)
+ {
+ _logger.Error(exception, "Error while disconnecting.");
+ }
+ finally
+ {
+ _adapter.Dispose();
+ }
+ }
+ }
+}
diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj
index 28e3f3d..a08f843 100644
--- a/Source/MQTTnet/MQTTnet.csproj
+++ b/Source/MQTTnet/MQTTnet.csproj
@@ -64,7 +64,7 @@
-
+
\ No newline at end of file
diff --git a/Source/MQTTnet/MqttFactory.cs b/Source/MQTTnet/MqttFactory.cs
index cb835f6..ffc8f90 100644
--- a/Source/MQTTnet/MqttFactory.cs
+++ b/Source/MQTTnet/MqttFactory.cs
@@ -1,16 +1,17 @@
-using System;
-using System.Collections.Generic;
-using MQTTnet.Adapter;
+using MQTTnet.Adapter;
using MQTTnet.Client;
using MQTTnet.Diagnostics;
using MQTTnet.Implementations;
+using MQTTnet.LowLevelClient;
using MQTTnet.Server;
+using System;
+using System.Collections.Generic;
namespace MQTTnet
{
- public class MqttFactory : IMqttFactory
+ public sealed class MqttFactory : IMqttFactory
{
- private IMqttClientAdapterFactory _clientAdapterFactory = new MqttClientAdapterFactory();
+ IMqttClientAdapterFactory _clientAdapterFactory = new MqttClientAdapterFactory();
public MqttFactory() : this(new MqttNetLogger())
{
@@ -29,6 +30,33 @@ namespace MQTTnet
return this;
}
+ public ILowLevelMqttClient CreateLowLevelMqttClient()
+ {
+ return CreateLowLevelMqttClient(DefaultLogger);
+ }
+
+ public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger)
+ {
+ if (logger == null) throw new ArgumentNullException(nameof(logger));
+
+ return new LowLevelMqttClient(_clientAdapterFactory, logger);
+ }
+
+ public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttClientAdapterFactory clientAdapterFactory)
+ {
+ if (clientAdapterFactory == null) throw new ArgumentNullException(nameof(clientAdapterFactory));
+
+ return new LowLevelMqttClient(_clientAdapterFactory, DefaultLogger);
+ }
+
+ public ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactoryy)
+ {
+ if (logger == null) throw new ArgumentNullException(nameof(logger));
+ if (clientAdapterFactoryy == null) throw new ArgumentNullException(nameof(clientAdapterFactoryy));
+
+ return new LowLevelMqttClient(_clientAdapterFactory, logger);
+ }
+
public IMqttClient CreateMqttClient()
{
return CreateMqttClient(DefaultLogger);
@@ -65,7 +93,7 @@ namespace MQTTnet
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
- return CreateMqttServer(new List { new MqttTcpServerAdapter(logger.CreateChildLogger()) }, logger);
+ return CreateMqttServer(new List { new MqttTcpServerAdapter(logger) }, logger);
}
public IMqttServer CreateMqttServer(IEnumerable serverAdapters, IMqttNetLogger logger)
@@ -73,14 +101,14 @@ namespace MQTTnet
if (serverAdapters == null) throw new ArgumentNullException(nameof(serverAdapters));
if (logger == null) throw new ArgumentNullException(nameof(logger));
- return new MqttServer(serverAdapters, logger.CreateChildLogger());
+ return new MqttServer(serverAdapters, logger);
}
public IMqttServer CreateMqttServer(IEnumerable serverAdapters)
{
if (serverAdapters == null) throw new ArgumentNullException(nameof(serverAdapters));
-
- return new MqttServer(serverAdapters, DefaultLogger.CreateChildLogger());
+
+ return new MqttServer(serverAdapters, DefaultLogger);
}
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet/Server/IMqttRetainedMessagesManager.cs b/Source/MQTTnet/Server/IMqttRetainedMessagesManager.cs
index 6ffdd2b..ab1d38c 100644
--- a/Source/MQTTnet/Server/IMqttRetainedMessagesManager.cs
+++ b/Source/MQTTnet/Server/IMqttRetainedMessagesManager.cs
@@ -1,12 +1,12 @@
-using System.Collections.Generic;
+using MQTTnet.Diagnostics;
+using System.Collections.Generic;
using System.Threading.Tasks;
-using MQTTnet.Diagnostics;
namespace MQTTnet.Server
{
public interface IMqttRetainedMessagesManager
{
- Task Start(IMqttServerOptions options, IMqttNetChildLogger logger);
+ Task Start(IMqttServerOptions options, IMqttNetLogger logger);
Task LoadMessagesAsync();
diff --git a/Source/MQTTnet/Server/MqttClientConnection.cs b/Source/MQTTnet/Server/MqttClientConnection.cs
index 5528969..a163b81 100644
--- a/Source/MQTTnet/Server/MqttClientConnection.cs
+++ b/Source/MQTTnet/Server/MqttClientConnection.cs
@@ -3,6 +3,7 @@ using MQTTnet.Client;
using MQTTnet.Diagnostics;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
+using MQTTnet.Implementations;
using MQTTnet.Internal;
using MQTTnet.PacketDispatcher;
using MQTTnet.Packets;
@@ -15,32 +16,34 @@ using System.Threading.Tasks;
namespace MQTTnet.Server
{
- public class MqttClientConnection : IDisposable
+ public sealed class MqttClientConnection : IDisposable
{
- private readonly MqttPacketIdentifierProvider _packetIdentifierProvider = new MqttPacketIdentifierProvider();
- private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
- private readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource();
+ readonly MqttPacketIdentifierProvider _packetIdentifierProvider = new MqttPacketIdentifierProvider();
+ readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
+ readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource();
- private readonly IMqttRetainedMessagesManager _retainedMessagesManager;
- private readonly MqttClientKeepAliveMonitor _keepAliveMonitor;
- private readonly MqttClientSessionsManager _sessionsManager;
+ readonly IMqttRetainedMessagesManager _retainedMessagesManager;
+ readonly MqttClientKeepAliveMonitor _keepAliveMonitor;
+ readonly MqttClientSessionsManager _sessionsManager;
- private readonly IMqttNetChildLogger _logger;
- private readonly IMqttServerOptions _serverOptions;
+ readonly IMqttNetLogger _logger;
+ readonly IMqttServerOptions _serverOptions;
- private readonly IMqttChannelAdapter _channelAdapter;
- private readonly IMqttDataConverter _dataConverter;
- private readonly string _endpoint;
- private readonly DateTime _connectedTimestamp;
+ readonly IMqttChannelAdapter _channelAdapter;
+ readonly IMqttDataConverter _dataConverter;
+ readonly string _endpoint;
+ readonly DateTime _connectedTimestamp;
- private Task _packageReceiverTask;
- private DateTime _lastPacketReceivedTimestamp;
- private DateTime _lastNonKeepAlivePacketReceivedTimestamp;
+ Task _packageReceiverTask;
+ DateTime _lastPacketReceivedTimestamp;
+ DateTime _lastNonKeepAlivePacketReceivedTimestamp;
- private long _receivedPacketsCount;
- private long _sentPacketsCount = 1; // Start with 1 because the CONNECT packet is not counted anywhere.
- private long _receivedApplicationMessagesCount;
- private long _sentApplicationMessagesCount;
+ long _receivedPacketsCount;
+ long _sentPacketsCount = 1; // Start with 1 because the CONNECT packet is not counted anywhere.
+ long _receivedApplicationMessagesCount;
+ long _sentApplicationMessagesCount;
+
+ bool _isTakeover;
public MqttClientConnection(
MqttConnectPacket connectPacket,
@@ -49,7 +52,7 @@ namespace MQTTnet.Server
IMqttServerOptions serverOptions,
MqttClientSessionsManager sessionsManager,
IMqttRetainedMessagesManager retainedMessagesManager,
- IMqttNetChildLogger logger)
+ IMqttNetLogger logger)
{
Session = session ?? throw new ArgumentNullException(nameof(session));
_serverOptions = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
@@ -64,7 +67,7 @@ namespace MQTTnet.Server
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateChildLogger(nameof(MqttClientConnection));
- _keepAliveMonitor = new MqttClientKeepAliveMonitor(ConnectPacket.ClientId, StopAsync, _logger);
+ _keepAliveMonitor = new MqttClientKeepAliveMonitor(ConnectPacket.ClientId, () => StopAsync(), _logger);
_connectedTimestamp = DateTime.UtcNow;
_lastPacketReceivedTimestamp = _connectedTimestamp;
@@ -77,15 +80,21 @@ namespace MQTTnet.Server
public MqttClientSession Session { get; }
- public async Task StopAsync()
+ public bool IsFinalized { get; set; }
+
+ public Task StopAsync(bool isTakeover = false)
{
+ _isTakeover = isTakeover;
+
StopInternal();
var task = _packageReceiverTask;
if (task != null)
{
- await task.ConfigureAwait(false);
+ return task;
}
+
+ return PlatformAbstractionLayer.CompletedTask;
}
public void ResetStatistics()
@@ -124,7 +133,7 @@ namespace MQTTnet.Server
return _packageReceiverTask;
}
- private async Task RunInternalAsync(MqttConnectionValidatorContext connectionValidatorContext)
+ async Task RunInternalAsync(MqttConnectionValidatorContext connectionValidatorContext)
{
var disconnectType = MqttClientDisconnectType.NotClean;
try
@@ -243,20 +252,25 @@ namespace MQTTnet.Server
_channelAdapter.ReadingPacketStartedCallback = null;
_channelAdapter.ReadingPacketCompletedCallback = null;
- _logger.Info("Client '{0}': Session stopped.", ClientId);
+ _logger.Info("Client '{0}': Connection stopped.", ClientId);
_packageReceiverTask = null;
}
+ if (_isTakeover)
+ {
+ return MqttClientDisconnectType.Takeover;
+ }
+
return disconnectType;
}
- private void StopInternal()
+ void StopInternal()
{
_cancellationToken.Cancel(false);
}
- private async Task EnqueueSubscribedRetainedMessagesAsync(ICollection topicFilters)
+ async Task EnqueueSubscribedRetainedMessagesAsync(ICollection topicFilters)
{
var retainedMessages = await _retainedMessagesManager.GetSubscribedMessagesAsync(topicFilters).ConfigureAwait(false);
foreach (var applicationMessage in retainedMessages)
@@ -265,7 +279,7 @@ namespace MQTTnet.Server
}
}
- private async Task HandleIncomingSubscribePacketAsync(MqttSubscribePacket subscribePacket)
+ async Task HandleIncomingSubscribePacketAsync(MqttSubscribePacket subscribePacket)
{
// TODO: Let the channel adapter create the packet.
var subscribeResult = await Session.SubscriptionsManager.SubscribeAsync(subscribePacket, ConnectPacket).ConfigureAwait(false);
@@ -281,14 +295,14 @@ namespace MQTTnet.Server
await EnqueueSubscribedRetainedMessagesAsync(subscribePacket.TopicFilters).ConfigureAwait(false);
}
- private async Task HandleIncomingUnsubscribePacketAsync(MqttUnsubscribePacket unsubscribePacket)
+ async Task HandleIncomingUnsubscribePacketAsync(MqttUnsubscribePacket unsubscribePacket)
{
// TODO: Let the channel adapter create the packet.
var unsubscribeResult = await Session.SubscriptionsManager.UnsubscribeAsync(unsubscribePacket).ConfigureAwait(false);
await SendAsync(unsubscribeResult).ConfigureAwait(false);
}
- private Task HandleIncomingPublishPacketAsync(MqttPublishPacket publishPacket)
+ Task HandleIncomingPublishPacketAsync(MqttPublishPacket publishPacket)
{
Interlocked.Increment(ref _sentApplicationMessagesCount);
@@ -313,16 +327,16 @@ namespace MQTTnet.Server
}
}
- private Task HandleIncomingPublishPacketWithQoS0Async(MqttPublishPacket publishPacket)
+ Task HandleIncomingPublishPacketWithQoS0Async(MqttPublishPacket publishPacket)
{
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
- return Task.FromResult(0);
+ return PlatformAbstractionLayer.CompletedTask;
}
- private Task HandleIncomingPublishPacketWithQoS1Async(MqttPublishPacket publishPacket)
+ Task HandleIncomingPublishPacketWithQoS1Async(MqttPublishPacket publishPacket)
{
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
@@ -331,7 +345,7 @@ namespace MQTTnet.Server
return SendAsync(pubAckPacket);
}
- private Task HandleIncomingPublishPacketWithQoS2Async(MqttPublishPacket publishPacket)
+ Task HandleIncomingPublishPacketWithQoS2Async(MqttPublishPacket publishPacket)
{
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
@@ -345,7 +359,7 @@ namespace MQTTnet.Server
return SendAsync(pubRecPacket);
}
- private async Task SendPendingPacketsAsync(CancellationToken cancellationToken)
+ async Task SendPendingPacketsAsync(CancellationToken cancellationToken)
{
MqttQueuedApplicationMessage queuedApplicationMessage = null;
MqttPublishPacket publishPacket = null;
@@ -422,9 +436,6 @@ namespace MQTTnet.Server
}
_logger.Verbose("Queued application message sent (ClientId: {0}).", ClientId);
-
- // TODO:
- //Interlocked.Increment(ref _sentPacketsCount);
}
}
catch (Exception exception)
@@ -459,7 +470,7 @@ namespace MQTTnet.Server
}
}
- private async Task SendAsync(MqttBasePacket packet)
+ async Task SendAsync(MqttBasePacket packet)
{
await _channelAdapter.SendPacketAsync(packet, _serverOptions.DefaultCommunicationTimeout, _cancellationToken.Token).ConfigureAwait(false);
@@ -471,12 +482,12 @@ namespace MQTTnet.Server
}
}
- private void OnAdapterReadingPacketCompleted()
+ void OnAdapterReadingPacketCompleted()
{
_keepAliveMonitor?.Resume();
}
- private void OnAdapterReadingPacketStarted()
+ void OnAdapterReadingPacketStarted()
{
_keepAliveMonitor?.Pause();
}
diff --git a/Source/MQTTnet/Server/MqttClientKeepAliveMonitor.cs b/Source/MQTTnet/Server/MqttClientKeepAliveMonitor.cs
index deefe4c..6b28825 100644
--- a/Source/MQTTnet/Server/MqttClientKeepAliveMonitor.cs
+++ b/Source/MQTTnet/Server/MqttClientKeepAliveMonitor.cs
@@ -1,27 +1,27 @@
-using System;
+using MQTTnet.Diagnostics;
+using MQTTnet.Internal;
+using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
-using MQTTnet.Diagnostics;
-using MQTTnet.Internal;
namespace MQTTnet.Server
{
public class MqttClientKeepAliveMonitor
{
- private readonly Stopwatch _lastPacketReceivedTracker = new Stopwatch();
+ readonly Stopwatch _lastPacketReceivedTracker = new Stopwatch();
- private readonly string _clientId;
- private readonly Func _keepAliveElapsedCallback;
- private readonly IMqttNetChildLogger _logger;
+ readonly string _clientId;
+ readonly Func _keepAliveElapsedCallback;
+ readonly IMqttNetLogger _logger;
- private bool _isPaused;
+ bool _isPaused;
- public MqttClientKeepAliveMonitor(string clientId, Func keepAliveElapsedCallback, IMqttNetChildLogger logger)
+ public MqttClientKeepAliveMonitor(string clientId, Func keepAliveElapsedCallback, IMqttNetLogger logger)
{
_clientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
_keepAliveElapsedCallback = keepAliveElapsedCallback ?? throw new ArgumentNullException(nameof(keepAliveElapsedCallback));
-
+
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateChildLogger(nameof(MqttClientKeepAliveMonitor));
}
@@ -32,7 +32,7 @@ namespace MQTTnet.Server
{
return;
}
-
+
Task.Run(() => RunAsync(keepAlivePeriod, cancellationToken), cancellationToken).Forget(_logger);
}
@@ -51,7 +51,7 @@ namespace MQTTnet.Server
_lastPacketReceivedTracker.Restart();
}
- private async Task RunAsync(int keepAlivePeriod, CancellationToken cancellationToken)
+ async Task RunAsync(int keepAlivePeriod, CancellationToken cancellationToken)
{
try
{
diff --git a/Source/MQTTnet/Server/MqttClientSession.cs b/Source/MQTTnet/Server/MqttClientSession.cs
index d097b9f..70b04d9 100644
--- a/Source/MQTTnet/Server/MqttClientSession.cs
+++ b/Source/MQTTnet/Server/MqttClientSession.cs
@@ -1,18 +1,18 @@
-using System;
+using MQTTnet.Diagnostics;
+using MQTTnet.Server.Status;
+using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using MQTTnet.Diagnostics;
-using MQTTnet.Server.Status;
namespace MQTTnet.Server
{
public class MqttClientSession
{
- private readonly IMqttNetChildLogger _logger;
+ readonly IMqttNetLogger _logger;
- private readonly DateTime _createdTimestamp = DateTime.UtcNow;
+ readonly DateTime _createdTimestamp = DateTime.UtcNow;
- public MqttClientSession(string clientId, IDictionary