mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-16 17:23:04 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
782dcffc62 | ||
|
|
40f7a7c593 | ||
|
|
9f4f37bb51 | ||
|
|
9051f8275b | ||
|
|
b23d25217b | ||
|
|
9afff6d8a0 | ||
|
|
ec41efd860 | ||
|
|
580a431fbf | ||
|
|
c06d84e834 | ||
|
|
06a299d212 | ||
|
|
f90985a1f9 | ||
|
|
677beddf07 | ||
|
|
7154a7b3dc | ||
|
|
7de3d79d09 |
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MQTTnet.AspNetCore</id>
|
<id>MQTTnet.AspNetCore</id>
|
||||||
<version>2.7.3</version>
|
<version>2.7.5</version>
|
||||||
<authors>Christian Kratky</authors>
|
<authors>Christian Kratky</authors>
|
||||||
<owners>Christian Kratky</owners>
|
<owners>Christian Kratky</owners>
|
||||||
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>This is a support library to integrate MQTTnet into AspNetCore.</description>
|
<description>This is a support library to integrate MQTTnet into AspNetCore.</description>
|
||||||
<releaseNotes>* Updated to MQTTnet 2.7.3.
|
<releaseNotes>* Updated to MQTTnet 2.7.5.
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2018</copyright>
|
<copyright>Copyright Christian Kratky 2016-2018</copyright>
|
||||||
<tags>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</tags>
|
<tags>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</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<group targetFramework="netstandard2.0">
|
<group targetFramework="netstandard2.0">
|
||||||
<dependency id="MQTTnet" version="2.7.3" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MQTTnet.Extensions.Rpc</id>
|
<id>MQTTnet.Extensions.Rpc</id>
|
||||||
<version>2.6.0</version>
|
<version>2.7.5</version>
|
||||||
<authors>Christian Kratky</authors>
|
<authors>Christian Kratky</authors>
|
||||||
<owners>Christian Kratky</owners>
|
<owners>Christian Kratky</owners>
|
||||||
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
||||||
@@ -10,32 +10,32 @@
|
|||||||
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>This is a extension library which allows executing synchronous device calls including a response using MQTTnet.</description>
|
<description>This is a extension library which allows executing synchronous device calls including a response using MQTTnet.</description>
|
||||||
<releaseNotes>* Initial version.
|
<releaseNotes>* Updated to MQTTnet 2.7.5.
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2017</copyright>
|
<copyright>Copyright Christian Kratky 2016-2017</copyright>
|
||||||
<tags>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</tags>
|
<tags>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</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<group targetFramework="netstandard2.0">
|
<group targetFramework="netstandard2.0">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
<group targetFramework="netstandard1.3">
|
<group targetFramework="netstandard1.3">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group targetFramework="netstandard2.0">
|
<group targetFramework="netstandard2.0">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group targetFramework="uap10.0">
|
<group targetFramework="uap10.0">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group targetFramework="net452">
|
<group targetFramework="net452">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group targetFramework="net461">
|
<group targetFramework="net461">
|
||||||
<dependency id="MQTTnet" version="2.6.0-rc1" />
|
<dependency id="MQTTnet" version="2.7.5" />
|
||||||
</group>
|
</group>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|||||||
+9
-10
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MQTTnet</id>
|
<id>MQTTnet</id>
|
||||||
<version>2.7.3</version>
|
<version>2.7.5</version>
|
||||||
<authors>Christian Kratky</authors>
|
<authors>Christian Kratky</authors>
|
||||||
<owners>Christian Kratky</owners>
|
<owners>Christian Kratky</owners>
|
||||||
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
||||||
@@ -10,14 +10,13 @@
|
|||||||
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
|
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
|
||||||
<releaseNotes>* [Core] Add several new extension methods.
|
<releaseNotes> * [Client] Fixed a deadlock while the client disconnects.
|
||||||
* [Client] Fixed an issue in _ManagedMqttClientOptionsBuilder_ when using _WithClientOptions_ and an options builder.
|
* [Client] Fixed broken support for protocol version 3.1.0.
|
||||||
* [Client] Added the "IsStarted" property for the managed client.
|
* [Server] The _MqttTcpServerAdapter_ is now added to the ASP.NET services.
|
||||||
* [Client] Optimized stream buffer for UWP apps.
|
* [Server] _MqttServerAdapter_ is renamed to _MqttTcpServerAdapter_ (BREAKING CHANGE!).
|
||||||
* [Client] Added the _BufferSize_ to the TCP options.
|
* [Server] The server no longer sends the will message of a client if the disconnect was clean (via _Disconnect_ packet).
|
||||||
* [Client] Fixed a race condition which leads to exceptions when reconnecting rapidly.
|
* [Server] The application message interceptor now allows closing the connection.
|
||||||
* [Server] Fixed a race condition which leads to exceptions when clients are reconnecting rapidly.
|
* [Server] Added a new flag for the _ClientDisconnected_ event which contains a value indicating whether the disconnect was clean (via _Disconnect_ packet).
|
||||||
* [Core] Fixed some issues in stream and socket handling.
|
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2018</copyright>
|
<copyright>Copyright Christian Kratky 2016-2018</copyright>
|
||||||
<tags>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</tags>
|
<tags>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</tags>
|
||||||
@@ -46,7 +45,7 @@
|
|||||||
|
|
||||||
<group targetFramework="net461">
|
<group targetFramework="net461">
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using MQTTnet.Adapter;
|
using MQTTnet.Adapter;
|
||||||
using MQTTnet.Diagnostics;
|
using MQTTnet.Diagnostics;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
|
using MQTTnet.Implementations;
|
||||||
|
|
||||||
namespace MQTTnet.AspNetCore
|
namespace MQTTnet.AspNetCore
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,9 @@ namespace MQTTnet.AspNetCore
|
|||||||
services.AddSingleton<IMqttServer>(s => s.GetService<MqttHostedServer>());
|
services.AddSingleton<IMqttServer>(s => s.GetService<MqttHostedServer>());
|
||||||
|
|
||||||
services.AddSingleton<MqttWebSocketServerAdapter>();
|
services.AddSingleton<MqttWebSocketServerAdapter>();
|
||||||
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttWebSocketServerAdapter>());
|
services.AddSingleton<MqttTcpServerAdapter>();
|
||||||
|
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttWebSocketServerAdapter>());
|
||||||
|
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttTcpServerAdapter>());
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace MQTTnet.Adapter
|
|||||||
public Task ConnectAsync(TimeSpan timeout)
|
public Task ConnectAsync(TimeSpan timeout)
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
_logger.Trace<MqttChannelAdapter>("Connecting [Timeout={0}]", timeout);
|
_logger.Verbose<MqttChannelAdapter>("Connecting [Timeout={0}]", timeout);
|
||||||
|
|
||||||
return ExecuteAndWrapExceptionAsync(() => _channel.ConnectAsync().TimeoutAfter(timeout));
|
return ExecuteAndWrapExceptionAsync(() => _channel.ConnectAsync().TimeoutAfter(timeout));
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ namespace MQTTnet.Adapter
|
|||||||
public Task DisconnectAsync(TimeSpan timeout)
|
public Task DisconnectAsync(TimeSpan timeout)
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
_logger.Trace<MqttChannelAdapter>("Disconnecting [Timeout={0}]", timeout);
|
_logger.Verbose<MqttChannelAdapter>("Disconnecting [Timeout={0}]", timeout);
|
||||||
|
|
||||||
return ExecuteAndWrapExceptionAsync(() => _channel.DisconnectAsync().TimeoutAfter(timeout));
|
return ExecuteAndWrapExceptionAsync(() => _channel.DisconnectAsync().TimeoutAfter(timeout));
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ namespace MQTTnet.Adapter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Trace<MqttChannelAdapter>("TX >>> {0} [Timeout={1}]", packet, timeout);
|
_logger.Verbose<MqttChannelAdapter>("TX >>> {0} [Timeout={1}]", packet, timeout);
|
||||||
|
|
||||||
var chunks = PacketSerializer.Serialize(packet);
|
var chunks = PacketSerializer.Serialize(packet);
|
||||||
foreach (var chunk in chunks)
|
foreach (var chunk in chunks)
|
||||||
@@ -135,7 +135,7 @@ namespace MQTTnet.Adapter
|
|||||||
throw new MqttProtocolViolationException("Received malformed packet.");
|
throw new MqttProtocolViolationException("Received malformed packet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Trace<MqttChannelAdapter>("RX <<< {0}", packet);
|
_logger.Verbose<MqttChannelAdapter>("RX <<< {0}", packet);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
public interface IMqttClientAdapterFactory
|
public interface IMqttClientAdapterFactory
|
||||||
{
|
{
|
||||||
IMqttChannelAdapter CreateClientAdapter(IMqttClientChannelOptions options, IMqttNetLogger logger);
|
IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
TimeSpan CommunicationTimeout { get; }
|
TimeSpan CommunicationTimeout { get; }
|
||||||
TimeSpan KeepAlivePeriod { get; }
|
TimeSpan KeepAlivePeriod { get; }
|
||||||
TimeSpan? KeepAliveSendInterval { get; set; }
|
TimeSpan? KeepAliveSendInterval { get; }
|
||||||
|
|
||||||
MqttProtocolVersion ProtocolVersion { get; }
|
MqttProtocolVersion ProtocolVersion { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -57,16 +57,16 @@ namespace MQTTnet.Client
|
|||||||
_packetIdentifierProvider.Reset();
|
_packetIdentifierProvider.Reset();
|
||||||
_packetDispatcher.Reset();
|
_packetDispatcher.Reset();
|
||||||
|
|
||||||
_adapter = _adapterFactory.CreateClientAdapter(options.ChannelOptions, _logger);
|
_adapter = _adapterFactory.CreateClientAdapter(options, _logger);
|
||||||
|
|
||||||
_logger.Trace<MqttClient>("Trying to connect with server.");
|
_logger.Verbose<MqttClient>("Trying to connect with server.");
|
||||||
await _adapter.ConnectAsync(_options.CommunicationTimeout).ConfigureAwait(false);
|
await _adapter.ConnectAsync(_options.CommunicationTimeout).ConfigureAwait(false);
|
||||||
_logger.Trace<MqttClient>("Connection with server established.");
|
_logger.Verbose<MqttClient>("Connection with server established.");
|
||||||
|
|
||||||
await StartReceivingPacketsAsync().ConfigureAwait(false);
|
await StartReceivingPacketsAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var connectResponse = await AuthenticateAsync(options.WillMessage).ConfigureAwait(false);
|
var connectResponse = await AuthenticateAsync(options.WillMessage).ConfigureAwait(false);
|
||||||
_logger.Trace<MqttClient>("MQTT connection with server established.");
|
_logger.Verbose<MqttClient>("MQTT connection with server established.");
|
||||||
|
|
||||||
_sendTracker.Restart();
|
_sendTracker.Restart();
|
||||||
|
|
||||||
@@ -77,12 +77,14 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
IsConnected = true;
|
IsConnected = true;
|
||||||
Connected?.Invoke(this, new MqttClientConnectedEventArgs(connectResponse.IsSessionPresent));
|
Connected?.Invoke(this, new MqttClientConnectedEventArgs(connectResponse.IsSessionPresent));
|
||||||
|
|
||||||
|
_logger.Info<MqttClient>("Connected.");
|
||||||
return new MqttClientConnectResult(connectResponse.IsSessionPresent);
|
return new MqttClientConnectResult(connectResponse.IsSessionPresent);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
_logger.Error<MqttClient>(exception, "Error while connecting with server.");
|
_logger.Error<MqttClient>(exception, "Error while connecting with server.");
|
||||||
await DisconnectInternalAsync(exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@@ -104,7 +106,7 @@ namespace MQTTnet.Client
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
await DisconnectInternalAsync(null, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +161,7 @@ namespace MQTTnet.Client
|
|||||||
case MqttQualityOfServiceLevel.AtMostOnce:
|
case MqttQualityOfServiceLevel.AtMostOnce:
|
||||||
{
|
{
|
||||||
// No packet identifier is used for QoS 0 [3.3.2.2 Packet Identifier]
|
// No packet identifier is used for QoS 0 [3.3.2.2 Packet Identifier]
|
||||||
await SendAsync((MqttPublishPacket[])qosGroup.ToArray()).ConfigureAwait(false);
|
await SendAsync(qosGroup.Cast<MqttBasePacket>().ToArray()).ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MqttQualityOfServiceLevel.AtLeastOnce:
|
case MqttQualityOfServiceLevel.AtLeastOnce:
|
||||||
@@ -236,33 +238,48 @@ namespace MQTTnet.Client
|
|||||||
if (IsConnected) throw new MqttProtocolViolationException(message);
|
if (IsConnected) throw new MqttProtocolViolationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DisconnectInternalAsync(Exception exception)
|
private async Task DisconnectInternalAsync(Task sender, Exception exception)
|
||||||
{
|
{
|
||||||
await _disconnectLock.WaitAsync();
|
await _disconnectLock.WaitAsync();
|
||||||
var clientWasConnected = IsConnected;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IsConnected = false;
|
|
||||||
|
|
||||||
if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested)
|
if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cancellationTokenSource.Cancel(false);
|
_cancellationTokenSource.Cancel(false);
|
||||||
|
}
|
||||||
|
catch (Exception adapterException)
|
||||||
|
{
|
||||||
|
_logger.Warning<MqttClient>(adapterException, "Error while disconnecting from adapter.");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_disconnectLock.Release();
|
||||||
|
}
|
||||||
|
|
||||||
if (_packetReceiverTask != null)
|
var clientWasConnected = IsConnected;
|
||||||
|
IsConnected = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_packetReceiverTask != null && _packetReceiverTask != sender)
|
||||||
{
|
{
|
||||||
Task.WaitAll(_packetReceiverTask);
|
_packetReceiverTask.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_keepAliveMessageSenderTask != null)
|
if (_keepAliveMessageSenderTask != null && _keepAliveMessageSenderTask != sender)
|
||||||
{
|
{
|
||||||
Task.WaitAll(_keepAliveMessageSenderTask);
|
_keepAliveMessageSenderTask.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _adapter.DisconnectAsync(_options.CommunicationTimeout).ConfigureAwait(false);
|
if (_adapter != null)
|
||||||
_logger.Trace<MqttClient>("Disconnected from adapter.");
|
{
|
||||||
|
await _adapter.DisconnectAsync(_options.CommunicationTimeout).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Verbose<MqttClient>("Disconnected from adapter.");
|
||||||
}
|
}
|
||||||
catch (Exception adapterException)
|
catch (Exception adapterException)
|
||||||
{
|
{
|
||||||
@@ -272,12 +289,9 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
_adapter?.Dispose();
|
_adapter?.Dispose();
|
||||||
_adapter = null;
|
_adapter = null;
|
||||||
|
|
||||||
_cancellationTokenSource?.Dispose();
|
_cancellationTokenSource?.Dispose();
|
||||||
_cancellationTokenSource = null;
|
_cancellationTokenSource = null;
|
||||||
|
|
||||||
_disconnectLock.Release();
|
|
||||||
|
|
||||||
_logger.Info<MqttClient>("Disconnected.");
|
_logger.Info<MqttClient>("Disconnected.");
|
||||||
Disconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(clientWasConnected, exception));
|
Disconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(clientWasConnected, exception));
|
||||||
}
|
}
|
||||||
@@ -287,8 +301,6 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Info<MqttClient>("Received <<< {0}", packet);
|
|
||||||
|
|
||||||
if (packet is MqttPublishPacket publishPacket)
|
if (packet is MqttPublishPacket publishPacket)
|
||||||
{
|
{
|
||||||
await ProcessReceivedPublishPacketAsync(publishPacket).ConfigureAwait(false);
|
await ProcessReceivedPublishPacketAsync(publishPacket).ConfigureAwait(false);
|
||||||
@@ -395,7 +407,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
private async Task SendKeepAliveMessagesAsync()
|
private async Task SendKeepAliveMessagesAsync()
|
||||||
{
|
{
|
||||||
_logger.Info<MqttClient>("Start sending keep alive packets.");
|
_logger.Verbose<MqttClient>("Start sending keep alive packets.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -415,37 +427,31 @@ namespace MQTTnet.Client
|
|||||||
await Task.Delay(keepAliveSendInterval, _cancellationTokenSource.Token).ConfigureAwait(false);
|
await Task.Delay(keepAliveSendInterval, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
if (_cancellationTokenSource.Token.IsCancellationRequested)
|
if (exception is OperationCanceledException)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (exception is MqttCommunicationException)
|
||||||
if (exception is MqttCommunicationException)
|
|
||||||
{
|
{
|
||||||
_logger.Warning<MqttClient>(exception, "MQTT communication exception while sending/receiving keep alive packets.");
|
_logger.Warning<MqttClient>(exception, "MQTT communication exception while sending/receiving keep alive packets.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Warning<MqttClient>(exception, "Unhandled exception while sending/receiving keep alive packets.");
|
_logger.Error<MqttClient>(exception, "Unhandled exception while sending/receiving keep alive packets.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await DisconnectInternalAsync(exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(_keepAliveMessageSenderTask, exception).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_logger.Info<MqttClient>("Stopped sending keep alive packets.");
|
_logger.Verbose<MqttClient>("Stopped sending keep alive packets.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ReceivePacketsAsync()
|
private async Task ReceivePacketsAsync()
|
||||||
{
|
{
|
||||||
_logger.Info<MqttClient>("Start receiving packets.");
|
_logger.Verbose<MqttClient>("Start receiving packets.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -463,31 +469,25 @@ namespace MQTTnet.Client
|
|||||||
StartProcessReceivedPacket(packet);
|
StartProcessReceivedPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
if (_cancellationTokenSource.IsCancellationRequested)
|
if (exception is OperationCanceledException)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (exception is MqttCommunicationException)
|
||||||
if (exception is MqttCommunicationException)
|
|
||||||
{
|
{
|
||||||
_logger.Warning<MqttClient>(exception, "MQTT communication exception while receiving packets.");
|
_logger.Warning<MqttClient>(exception, "MQTT communication exception while receiving packets.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Error<MqttClient>(exception, "Unhandled exception while receiving packets.");
|
_logger.Error<MqttClient>(exception, "Unhandled exception while receiving packets.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await DisconnectInternalAsync(exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_logger.Info<MqttClient>("Stopped receiving packets.");
|
_logger.Verbose<MqttClient>("Stopped receiving packets.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace MQTTnet.Diagnostics
|
|||||||
{
|
{
|
||||||
event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
||||||
|
|
||||||
void Trace<TSource>(string message, params object[] parameters);
|
void Verbose<TSource>(string message, params object[] parameters);
|
||||||
|
|
||||||
void Info<TSource>(string message, params object[] parameters);
|
void Info<TSource>(string message, params object[] parameters);
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace MQTTnet.Diagnostics
|
|||||||
|
|
||||||
public event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
public event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
|
||||||
|
|
||||||
public void Trace<TSource>(string message, params object[] parameters)
|
public void Verbose<TSource>(string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish<TSource>(MqttNetLogLevel.Verbose, null, message, parameters);
|
Publish<TSource>(MqttNetLogLevel.Verbose, null, message, parameters);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,28 @@ namespace MQTTnet.Implementations
|
|||||||
{
|
{
|
||||||
public class MqttClientAdapterFactory : IMqttClientAdapterFactory
|
public class MqttClientAdapterFactory : IMqttClientAdapterFactory
|
||||||
{
|
{
|
||||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientChannelOptions options, IMqttNetLogger logger)
|
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
|
||||||
{
|
{
|
||||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||||
|
|
||||||
switch (options)
|
var serializer = new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion };
|
||||||
|
|
||||||
|
switch (options.ChannelOptions)
|
||||||
{
|
{
|
||||||
case MqttClientTcpOptions tcpOptions:
|
case MqttClientTcpOptions tcpOptions:
|
||||||
return new MqttChannelAdapter(new MqttTcpChannel(tcpOptions), new MqttPacketSerializer(), logger);
|
{
|
||||||
|
return new MqttChannelAdapter(new MqttTcpChannel(tcpOptions), serializer, logger);
|
||||||
|
}
|
||||||
|
|
||||||
case MqttClientWebSocketOptions webSocketOptions:
|
case MqttClientWebSocketOptions webSocketOptions:
|
||||||
return new MqttChannelAdapter(new MqttWebSocketChannel(webSocketOptions), new MqttPacketSerializer(), logger);
|
{
|
||||||
|
return new MqttChannelAdapter(new MqttWebSocketChannel(webSocketOptions), serializer, logger);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException();
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -9,12 +9,12 @@ using MQTTnet.Server;
|
|||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public class MqttServerAdapter : IMqttServerAdapter, IDisposable
|
public class MqttTcpServerAdapter : IMqttServerAdapter, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IMqttNetLogger _logger;
|
private readonly IMqttNetLogger _logger;
|
||||||
private StreamSocketListener _defaultEndpointSocket;
|
private StreamSocketListener _defaultEndpointSocket;
|
||||||
|
|
||||||
public MqttServerAdapter(IMqttNetLogger logger)
|
public MqttTcpServerAdapter(IMqttNetLogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ namespace MQTTnet.Implementations
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
_logger.Error<MqttServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -14,7 +14,7 @@ using MQTTnet.Server;
|
|||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public class MqttServerAdapter : IMqttServerAdapter, IDisposable
|
public class MqttTcpServerAdapter : IMqttServerAdapter, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IMqttNetLogger _logger;
|
private readonly IMqttNetLogger _logger;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ namespace MQTTnet.Implementations
|
|||||||
private Socket _tlsEndpointSocket;
|
private Socket _tlsEndpointSocket;
|
||||||
private X509Certificate2 _tlsCertificate;
|
private X509Certificate2 _tlsCertificate;
|
||||||
|
|
||||||
public MqttServerAdapter(IMqttNetLogger logger)
|
public MqttTcpServerAdapter(IMqttNetLogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ namespace MQTTnet.Implementations
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error<MqttServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at default endpoint.");
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ namespace MQTTnet.Implementations
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Error<MqttServerAdapter>(exception, "Error while accepting connection at TLS endpoint.");
|
_logger.Error<MqttTcpServerAdapter>(exception, "Error while accepting connection at TLS endpoint.");
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ using MQTTnet.Client;
|
|||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public sealed class MqttWebSocketChannel : IMqttChannel, IDisposable
|
public sealed class MqttWebSocketChannel : IMqttChannel
|
||||||
{
|
{
|
||||||
// ReSharper disable once MemberCanBePrivate.Global
|
// ReSharper disable once MemberCanBePrivate.Global
|
||||||
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
|
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ namespace MQTTnet.ManagedClient
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_logger.Trace<ManagedMqttClient>("Stopped publishing messages.");
|
_logger.Verbose<ManagedMqttClient>("Stopped publishing messages.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,14 @@ namespace MQTTnet
|
|||||||
public IMqttServer CreateMqttServer()
|
public IMqttServer CreateMqttServer()
|
||||||
{
|
{
|
||||||
var logger = new MqttNetLogger();
|
var logger = new MqttNetLogger();
|
||||||
return CreateMqttServer(new List<IMqttServerAdapter> { new MqttServerAdapter(logger) }, logger);
|
return CreateMqttServer(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMqttServer CreateMqttServer(IMqttNetLogger logger)
|
||||||
|
{
|
||||||
|
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||||
|
|
||||||
|
return CreateMqttServer(new List<IMqttServerAdapter> { new MqttTcpServerAdapter(logger) }, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
|
public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
|
||||||
|
|||||||
@@ -11,5 +11,9 @@
|
|||||||
public string ClientId { get; }
|
public string ClientId { get; }
|
||||||
|
|
||||||
public MqttApplicationMessage ApplicationMessage { get; set; }
|
public MqttApplicationMessage ApplicationMessage { get; set; }
|
||||||
|
|
||||||
|
public bool AcceptPublish { get; set; } = true;
|
||||||
|
|
||||||
|
public bool CloseConnection { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
public class MqttClientDisconnectedEventArgs : EventArgs
|
public class MqttClientDisconnectedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public MqttClientDisconnectedEventArgs(ConnectedMqttClient client)
|
public MqttClientDisconnectedEventArgs(ConnectedMqttClient client, bool wasCleanDisconnect)
|
||||||
{
|
{
|
||||||
Client = client ?? throw new ArgumentNullException(nameof(client));
|
Client = client ?? throw new ArgumentNullException(nameof(client));
|
||||||
|
WasCleanDisconnect = wasCleanDisconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectedMqttClient Client { get; }
|
public ConnectedMqttClient Client { get; }
|
||||||
|
|
||||||
|
public bool WasCleanDisconnect { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace MQTTnet.Server
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_logger.Trace<MqttClientSession>("Client {0}: Stopped checking keep alive timeout.", _clientId);
|
_logger.Verbose<MqttClientSession>("Client {0}: Stopped checking keep alive timeout.", _clientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace MQTTnet.Server
|
|||||||
_queue.Enqueue(packet);
|
_queue.Enqueue(packet);
|
||||||
_queueWaitSemaphore.Release();
|
_queueWaitSemaphore.Release();
|
||||||
|
|
||||||
_logger.Trace<MqttClientPendingMessagesQueue>("Enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
_logger.Verbose<MqttClientPendingMessagesQueue>("Enqueued packet (ClientId: {0}).", _clientSession.ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendQueuedPacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
private async Task SendQueuedPacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
|
||||||
@@ -96,7 +96,7 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { packet }).ConfigureAwait(false);
|
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { packet }).ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.Trace<MqttClientPendingMessagesQueue>("Enqueued packet sent (ClientId: {0}).", _clientSession.ClientId);
|
_logger.Verbose<MqttClientPendingMessagesQueue>("Enqueued packet sent (ClientId: {0}).", _clientSession.ClientId);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace MQTTnet.Server
|
|||||||
private IMqttChannelAdapter _adapter;
|
private IMqttChannelAdapter _adapter;
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
private MqttApplicationMessage _willMessage;
|
private MqttApplicationMessage _willMessage;
|
||||||
|
private bool _wasCleanDisconnect;
|
||||||
|
|
||||||
public MqttClientSession(
|
public MqttClientSession(
|
||||||
string clientId,
|
string clientId,
|
||||||
@@ -55,7 +56,7 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
public bool IsConnected => _adapter != null;
|
public bool IsConnected => _adapter != null;
|
||||||
|
|
||||||
public async Task RunAsync(MqttConnectPacket connectPacket, IMqttChannelAdapter adapter)
|
public async Task<bool> RunAsync(MqttConnectPacket connectPacket, IMqttChannelAdapter adapter)
|
||||||
{
|
{
|
||||||
if (connectPacket == null) throw new ArgumentNullException(nameof(connectPacket));
|
if (connectPacket == null) throw new ArgumentNullException(nameof(connectPacket));
|
||||||
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
|
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
|
||||||
@@ -64,6 +65,7 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
var cancellationTokenSource = new CancellationTokenSource();
|
var cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
_wasCleanDisconnect = false;
|
||||||
_willMessage = connectPacket.WillMessage;
|
_willMessage = connectPacket.WillMessage;
|
||||||
_adapter = adapter;
|
_adapter = adapter;
|
||||||
_cancellationTokenSource = cancellationTokenSource;
|
_cancellationTokenSource = cancellationTokenSource;
|
||||||
@@ -84,9 +86,11 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
_logger.Error<MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
_logger.Error<MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return _wasCleanDisconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopAsync()
|
public async Task StopAsync(bool wasCleanDisconnect = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -95,6 +99,8 @@ namespace MQTTnet.Server
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_wasCleanDisconnect = wasCleanDisconnect;
|
||||||
|
|
||||||
_cancellationTokenSource?.Cancel(false);
|
_cancellationTokenSource?.Cancel(false);
|
||||||
|
|
||||||
PendingMessagesQueue.WaitForCompletion();
|
PendingMessagesQueue.WaitForCompletion();
|
||||||
@@ -110,9 +116,10 @@ namespace MQTTnet.Server
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
var willMessage = _willMessage;
|
var willMessage = _willMessage;
|
||||||
if (willMessage != null)
|
_willMessage = null; // clear willmessage so it is send just once
|
||||||
|
|
||||||
|
if (willMessage != null && !wasCleanDisconnect)
|
||||||
{
|
{
|
||||||
_willMessage = null; // clear willmessage so it is send just once
|
|
||||||
await ApplicationMessageReceivedCallback(this, willMessage).ConfigureAwait(false);
|
await ApplicationMessageReceivedCallback(this, willMessage).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,7 +253,12 @@ namespace MQTTnet.Server
|
|||||||
return HandleIncomingUnsubscribePacketAsync(adapter, unsubscribePacket, cancellationToken);
|
return HandleIncomingUnsubscribePacketAsync(adapter, unsubscribePacket, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet is MqttDisconnectPacket || packet is MqttConnectPacket)
|
if (packet is MqttDisconnectPacket)
|
||||||
|
{
|
||||||
|
return StopAsync(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet is MqttConnectPacket)
|
||||||
{
|
{
|
||||||
return StopAsync();
|
return StopAsync();
|
||||||
}
|
}
|
||||||
@@ -262,7 +274,6 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
if (subscribeResult.CloseConnection)
|
if (subscribeResult.CloseConnection)
|
||||||
{
|
{
|
||||||
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { new MqttDisconnectPacket() }).ConfigureAwait(false);
|
|
||||||
await StopAsync().ConfigureAwait(false);
|
await StopAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace MQTTnet.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Action<ConnectedMqttClient> ClientConnectedCallback { get; set; }
|
public Action<ConnectedMqttClient> ClientConnectedCallback { get; set; }
|
||||||
public Action<ConnectedMqttClient> ClientDisconnectedCallback { get; set; }
|
public Action<ConnectedMqttClient, bool> ClientDisconnectedCallback { get; set; }
|
||||||
public Action<string, TopicFilter> ClientSubscribedTopicCallback { get; set; }
|
public Action<string, TopicFilter> ClientSubscribedTopicCallback { get; set; }
|
||||||
public Action<string, string> ClientUnsubscribedTopicCallback { get; set; }
|
public Action<string, string> ClientUnsubscribedTopicCallback { get; set; }
|
||||||
public Action<string, MqttApplicationMessage> ApplicationMessageReceivedCallback { get; set; }
|
public Action<string, MqttApplicationMessage> ApplicationMessageReceivedCallback { get; set; }
|
||||||
@@ -37,7 +37,9 @@ namespace MQTTnet.Server
|
|||||||
public async Task RunSessionAsync(IMqttChannelAdapter clientAdapter, CancellationToken cancellationToken)
|
public async Task RunSessionAsync(IMqttChannelAdapter clientAdapter, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var clientId = string.Empty;
|
var clientId = string.Empty;
|
||||||
|
var wasCleanDisconnect = false;
|
||||||
MqttClientSession clientSession = null;
|
MqttClientSession clientSession = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken)
|
if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken)
|
||||||
@@ -84,7 +86,7 @@ namespace MQTTnet.Server
|
|||||||
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
|
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
|
||||||
});
|
});
|
||||||
|
|
||||||
await clientSession.RunAsync(connectPacket, clientAdapter).ConfigureAwait(false);
|
wasCleanDisconnect = await clientSession.RunAsync(connectPacket, clientAdapter).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
@@ -110,7 +112,8 @@ namespace MQTTnet.Server
|
|||||||
ClientId = clientId,
|
ClientId = clientId,
|
||||||
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion,
|
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion,
|
||||||
PendingApplicationMessages = clientSession?.PendingMessagesQueue.Count ?? 0
|
PendingApplicationMessages = clientSession?.PendingMessagesQueue.Count ?? 0
|
||||||
});
|
},
|
||||||
|
wasCleanDisconnect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,8 +159,13 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
applicationMessage = InterceptApplicationMessage(senderClientSession, applicationMessage);
|
var interceptorContext = InterceptApplicationMessage(senderClientSession, applicationMessage);
|
||||||
if (applicationMessage == null)
|
if (interceptorContext.CloseConnection)
|
||||||
|
{
|
||||||
|
await senderClientSession.StopAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interceptorContext.ApplicationMessage == null || !interceptorContext.AcceptPublish)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -230,20 +238,20 @@ namespace MQTTnet.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MqttApplicationMessage InterceptApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
|
private MqttApplicationMessageInterceptorContext InterceptApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
|
||||||
{
|
{
|
||||||
var interceptor = _options.ApplicationMessageInterceptor;
|
|
||||||
if (interceptor == null)
|
|
||||||
{
|
|
||||||
return applicationMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
var interceptorContext = new MqttApplicationMessageInterceptorContext(
|
var interceptorContext = new MqttApplicationMessageInterceptorContext(
|
||||||
senderClientSession?.ClientId,
|
senderClientSession?.ClientId,
|
||||||
applicationMessage);
|
applicationMessage);
|
||||||
|
|
||||||
|
var interceptor = _options.ApplicationMessageInterceptor;
|
||||||
|
if (interceptor == null)
|
||||||
|
{
|
||||||
|
return interceptorContext;
|
||||||
|
}
|
||||||
|
|
||||||
interceptor(interceptorContext);
|
interceptor(interceptorContext);
|
||||||
return interceptorContext.ApplicationMessage;
|
return interceptorContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MqttConnectReturnCode ValidateConnection(MqttConnectPacket connectPacket)
|
private MqttConnectReturnCode ValidateConnection(MqttConnectPacket connectPacket)
|
||||||
@@ -279,11 +287,11 @@ namespace MQTTnet.Server
|
|||||||
clientSession.Dispose();
|
clientSession.Dispose();
|
||||||
clientSession = null;
|
clientSession = null;
|
||||||
|
|
||||||
_logger.Trace<MqttClientSessionsManager>("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
_logger.Verbose<MqttClientSessionsManager>("Stopped existing session of client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Trace<MqttClientSessionsManager>("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
_logger.Verbose<MqttClientSessionsManager>("Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +310,7 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
_sessions[connectPacket.ClientId] = clientSession;
|
_sessions[connectPacket.ClientId] = clientSession;
|
||||||
|
|
||||||
_logger.Trace<MqttClientSessionsManager>("Created a new session for client '{0}'.", connectPacket.ClientId);
|
_logger.Verbose<MqttClientSessionsManager>("Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
if (!saveIsRequired)
|
if (!saveIsRequired)
|
||||||
{
|
{
|
||||||
_logger.Trace<MqttRetainedMessagesManager>("Skipped saving retained messages because no changes were detected.");
|
_logger.Verbose<MqttRetainedMessagesManager>("Skipped saving retained messages because no changes were detected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saveIsRequired && _options.Storage != null)
|
if (saveIsRequired && _options.Storage != null)
|
||||||
|
|||||||
@@ -138,10 +138,10 @@ namespace MQTTnet.Server
|
|||||||
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(client));
|
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientDisconnected(ConnectedMqttClient client)
|
private void OnClientDisconnected(ConnectedMqttClient client, bool wasCleanDisconnect)
|
||||||
{
|
{
|
||||||
_logger.Info<MqttServer>("Client '{0}': Disconnected.", client.ClientId);
|
_logger.Info<MqttServer>("Client '{0}': Disconnected (clean={1}).", client.ClientId, wasCleanDisconnect);
|
||||||
ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(client));
|
ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(client, wasCleanDisconnect));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientSubscribedTopic(string clientId, TopicFilter topicFilter)
|
private void OnClientSubscribedTopic(string clientId, TopicFilter topicFilter)
|
||||||
@@ -162,7 +162,7 @@ namespace MQTTnet.Server
|
|||||||
private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
|
private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
eventArgs.SessionTask = Task.Run(
|
eventArgs.SessionTask = Task.Run(
|
||||||
async () => await _clientSessionsManager.RunSessionAsync(eventArgs.Client, _cancellationTokenSource.Token).ConfigureAwait(false),
|
() => _clientSessionsManager.RunSessionAsync(eventArgs.Client, _cancellationTokenSource.Token),
|
||||||
_cancellationTokenSource.Token);
|
_cancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">netstandard1.3;netstandard2.0;net452;net461;uap10.0</TargetFrameworks>
|
|
||||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard1.3;netstandard2.0</TargetFrameworks>
|
|
||||||
<AssemblyName>MQTTnet</AssemblyName>
|
|
||||||
<RootNamespace>MQTTnet</RootNamespace>
|
|
||||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
|
||||||
<DebugType>Full</DebugType>
|
|
||||||
<AssemblyVersion>0.0.0.0</AssemblyVersion>
|
|
||||||
<FileVersion>0.0.0.0</FileVersion>
|
|
||||||
<Version>0.0.0.0</Version>
|
|
||||||
<Company />
|
|
||||||
<Product />
|
|
||||||
<Description />
|
|
||||||
<Authors />
|
|
||||||
<PackageId />
|
|
||||||
<SignAssembly>false</SignAssembly>
|
|
||||||
<DelaySign>false</DelaySign>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
|
|
||||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
|
||||||
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker>
|
|
||||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
|
||||||
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
|
|
||||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
|
||||||
<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier>
|
|
||||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
|
||||||
<DefineConstants>$(DefineConstants);WINDOWS_UWP</DefineConstants>
|
|
||||||
<DefaultLanguage>en</DefaultLanguage>
|
|
||||||
<LanguageTargets>$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets</LanguageTargets>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" />
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard1.3|AnyCPU'">
|
|
||||||
<DefineConstants>RELEASE;NETSTANDARD1_3</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
|
|
||||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
|
||||||
<PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
|
|
||||||
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.3'">
|
|
||||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
|
||||||
<PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
|
|
||||||
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='uap10.0'">
|
|
||||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="5.4.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='net452'">
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
+2
-1
@@ -11,13 +11,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Frameworks", "Frameworks",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.TestApp.UniversalWindows", "Tests\MQTTnet.TestApp.UniversalWindows\MQTTnet.TestApp.UniversalWindows.csproj", "{FF1F72D6-9524-4422-9497-3CC0002216ED}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.TestApp.UniversalWindows", "Tests\MQTTnet.TestApp.UniversalWindows\MQTTnet.TestApp.UniversalWindows.csproj", "{FF1F72D6-9524-4422-9497-3CC0002216ED}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.NetStandard", "Frameworks\MQTTnet.Netstandard\MQTTnet.NetStandard.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.NetStandard", "Frameworks\MQTTnet.NetStandard\MQTTnet.Netstandard.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
appveyor.yml = appveyor.yml
|
appveyor.yml = appveyor.yml
|
||||||
Build\build.ps1 = Build\build.ps1
|
Build\build.ps1 = Build\build.ps1
|
||||||
Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec
|
Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec
|
||||||
|
Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec
|
||||||
Build\MQTTnet.nuspec = Build\MQTTnet.nuspec
|
Build\MQTTnet.nuspec = Build\MQTTnet.nuspec
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ If you want to contribute to this project just create a pull request. But only p
|
|||||||
This library is used in the following projects:
|
This library is used in the following projects:
|
||||||
|
|
||||||
* MQTT Client Rx (Wrapper for Reactive Extensions, <https://github.com/1iveowl/MQTTClient.rx>)
|
* MQTT Client Rx (Wrapper for Reactive Extensions, <https://github.com/1iveowl/MQTTClient.rx>)
|
||||||
* MQTT Tester (MQTT client test app for [Android](https://play.google.com/store/apps/details?id=com.liveowl.mqtttester), [iOS](https://itunes.apple.com/us/app/mqtt-tester/id1278621826?mt=8), and [Windows 10](https://www.microsoft.com/en-us/store/p/mqtt-tester/9wzdncrd272c))
|
* MQTT Tester (MQTT client test app for [Android](https://play.google.com/store/apps/details?id=com.liveowl.mqtttester) and [iOS](https://itunes.apple.com/us/app/mqtt-tester/id1278621826?mt=8))
|
||||||
* Wirehome (Open Source Home Automation system for .NET, <https://github.com/chkr1011/Wirehome>)
|
* Wirehome (Open Source Home Automation system for .NET, <https://github.com/chkr1011/Wirehome>)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace MQTTnet.Core.Tests
|
|||||||
await s.StopAsync();
|
await s.StopAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(1, receivedMessagesCount);
|
Assert.AreEqual(0, receivedMessagesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@@ -209,12 +209,9 @@ namespace MQTTnet.Core.Tests
|
|||||||
await s.StartAsync(new MqttServerOptions());
|
await s.StartAsync(new MqttServerOptions());
|
||||||
|
|
||||||
var c1 = await serverAdapter.ConnectTestClient(s, "c1");
|
var c1 = await serverAdapter.ConnectTestClient(s, "c1");
|
||||||
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
await c1.PublishAndWaitForAsync(s, new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
||||||
await c1.DisconnectAsync();
|
await c1.DisconnectAsync();
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(2));
|
|
||||||
// TODO: Find another way to wait for the retained components.
|
|
||||||
|
|
||||||
var c2 = await serverAdapter.ConnectTestClient(s, "c2");
|
var c2 = await serverAdapter.ConnectTestClient(s, "c2");
|
||||||
c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
||||||
await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("retained").Build());
|
await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("retained").Build());
|
||||||
@@ -244,7 +241,7 @@ namespace MQTTnet.Core.Tests
|
|||||||
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
||||||
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[0]).WithRetainFlag().Build());
|
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[0]).WithRetainFlag().Build());
|
||||||
await c1.DisconnectAsync();
|
await c1.DisconnectAsync();
|
||||||
|
|
||||||
var c2 = await serverAdapter.ConnectTestClient(s, "c2");
|
var c2 = await serverAdapter.ConnectTestClient(s, "c2");
|
||||||
c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
||||||
await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
|
await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
|
||||||
@@ -274,7 +271,8 @@ namespace MQTTnet.Core.Tests
|
|||||||
await s.StartAsync(options);
|
await s.StartAsync(options);
|
||||||
|
|
||||||
var c1 = await serverAdapter.ConnectTestClient(s, "c1");
|
var c1 = await serverAdapter.ConnectTestClient(s, "c1");
|
||||||
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
|
||||||
|
await c1.PublishAndWaitForAsync(s, new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
||||||
await c1.DisconnectAsync();
|
await c1.DisconnectAsync();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -282,8 +280,7 @@ namespace MQTTnet.Core.Tests
|
|||||||
await s.StopAsync();
|
await s.StopAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(2));
|
Assert.AreEqual(1, storage.Messages.Count);
|
||||||
// TODO: Find another way to wait for the retained components.
|
|
||||||
|
|
||||||
s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
|
s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
|
||||||
|
|
||||||
@@ -385,17 +382,17 @@ namespace MQTTnet.Core.Tests
|
|||||||
|
|
||||||
private class TestStorage : IMqttServerStorage
|
private class TestStorage : IMqttServerStorage
|
||||||
{
|
{
|
||||||
private IList<MqttApplicationMessage> _messages = new List<MqttApplicationMessage>();
|
public IList<MqttApplicationMessage> Messages = new List<MqttApplicationMessage>();
|
||||||
|
|
||||||
public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
|
public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
|
||||||
{
|
{
|
||||||
_messages = messages;
|
Messages = messages;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
|
public Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
|
||||||
{
|
{
|
||||||
return Task.FromResult(_messages);
|
return Task.FromResult(Messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Tests
|
|||||||
_adapter = adapter;
|
_adapter = adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMqttChannelAdapter CreateClientAdapter(IMqttClientChannelOptions options, IMqttNetLogger logger)
|
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetLogger logger)
|
||||||
{
|
{
|
||||||
return _adapter;
|
return _adapter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using MQTTnet.Client;
|
||||||
|
using MQTTnet.Server;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MQTTnet.Core.Tests
|
||||||
|
{
|
||||||
|
public static class TestServerExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// publishes a message with a client and waits in the server until a message with the same topic is received
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task PublishAndWaitForAsync(this IMqttClient client, IMqttServer server, MqttApplicationMessage message)
|
||||||
|
{
|
||||||
|
var tcs = new TaskCompletionSource<object>();
|
||||||
|
|
||||||
|
EventHandler<MqttApplicationMessageReceivedEventArgs> handler = (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.ApplicationMessage.Topic == message.Topic)
|
||||||
|
{
|
||||||
|
tcs.SetResult(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
server.ApplicationMessageReceived += handler;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await client.PublishAsync(message).ConfigureAwait(false);
|
||||||
|
await tcs.Task.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
server.ApplicationMessageReceived -= handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using MQTTnet;
|
||||||
using MQTTnet.AspNetCore;
|
using MQTTnet.AspNetCore;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace MQTTnet.TestApp.NetCore
|
namespace MQTTnet.TestApp.NetCore
|
||||||
{
|
{
|
||||||
@@ -38,6 +37,12 @@ namespace MQTTnet.TestApp.NetCore
|
|||||||
// based payload with the timestamp is a suitable use case.
|
// based payload with the timestamp is a suitable use case.
|
||||||
context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
|
context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.ApplicationMessage.Topic == "not_allowed_topic")
|
||||||
|
{
|
||||||
|
context.AcceptPublish = false;
|
||||||
|
context.CloseConnection = true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SubscriptionInterceptor = context =>
|
SubscriptionInterceptor = context =>
|
||||||
{
|
{
|
||||||
@@ -72,27 +77,27 @@ namespace MQTTnet.TestApp.NetCore
|
|||||||
ConsoleColor.Magenta);
|
ConsoleColor.Magenta);
|
||||||
};
|
};
|
||||||
|
|
||||||
options.ApplicationMessageInterceptor = c =>
|
//options.ApplicationMessageInterceptor = c =>
|
||||||
{
|
//{
|
||||||
if (c.ApplicationMessage.Payload == null || c.ApplicationMessage.Payload.Length == 0)
|
// if (c.ApplicationMessage.Payload == null || c.ApplicationMessage.Payload.Length == 0)
|
||||||
{
|
// {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
var content = JObject.Parse(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
|
// var content = JObject.Parse(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
|
||||||
var timestampProperty = content.Property("timestamp");
|
// var timestampProperty = content.Property("timestamp");
|
||||||
if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null)
|
// if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null)
|
||||||
{
|
// {
|
||||||
timestampProperty.Value = DateTime.Now.ToString("O");
|
// timestampProperty.Value = DateTime.Now.ToString("O");
|
||||||
c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(content.ToString());
|
// c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(content.ToString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
catch (Exception)
|
// catch (Exception)
|
||||||
{
|
// {
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
mqttServer.ClientDisconnected += (s, e) =>
|
mqttServer.ClientDisconnected += (s, e) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ using MQTTnet.Implementations;
|
|||||||
using MQTTnet.ManagedClient;
|
using MQTTnet.ManagedClient;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
|
using MqttClientConnectedEventArgs = MQTTnet.Client.MqttClientConnectedEventArgs;
|
||||||
|
using MqttClientDisconnectedEventArgs = MQTTnet.Client.MqttClientDisconnectedEventArgs;
|
||||||
|
|
||||||
namespace MQTTnet.TestApp.UniversalWindows
|
namespace MQTTnet.TestApp.UniversalWindows
|
||||||
{
|
{
|
||||||
@@ -33,6 +35,11 @@ namespace MQTTnet.TestApp.UniversalWindows
|
|||||||
private async void OnTraceMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
private async void OnTraceMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
||||||
{
|
{
|
||||||
_traceMessages.Enqueue(e.TraceMessage);
|
_traceMessages.Enqueue(e.TraceMessage);
|
||||||
|
await UpdateLogAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateLogAsync()
|
||||||
|
{
|
||||||
while (_traceMessages.Count > 100)
|
while (_traceMessages.Count > 100)
|
||||||
{
|
{
|
||||||
_traceMessages.TryDequeue(out _);
|
_traceMessages.TryDequeue(out _);
|
||||||
@@ -113,11 +120,15 @@ namespace MQTTnet.TestApp.UniversalWindows
|
|||||||
{
|
{
|
||||||
await _mqttClient.DisconnectAsync();
|
await _mqttClient.DisconnectAsync();
|
||||||
_mqttClient.ApplicationMessageReceived -= OnApplicationMessageReceived;
|
_mqttClient.ApplicationMessageReceived -= OnApplicationMessageReceived;
|
||||||
|
_mqttClient.Connected -= OnConnected;
|
||||||
|
_mqttClient.Disconnected -= OnDisconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
var factory = new MqttFactory();
|
var factory = new MqttFactory();
|
||||||
_mqttClient = factory.CreateMqttClient();
|
_mqttClient = factory.CreateMqttClient();
|
||||||
_mqttClient.ApplicationMessageReceived += OnApplicationMessageReceived;
|
_mqttClient.ApplicationMessageReceived += OnApplicationMessageReceived;
|
||||||
|
_mqttClient.Connected += OnConnected;
|
||||||
|
_mqttClient.Disconnected += OnDisconnected;
|
||||||
|
|
||||||
await _mqttClient.ConnectAsync(options);
|
await _mqttClient.ConnectAsync(options);
|
||||||
}
|
}
|
||||||
@@ -127,6 +138,22 @@ namespace MQTTnet.TestApp.UniversalWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDisconnected(object sender, MqttClientDisconnectedEventArgs e)
|
||||||
|
{
|
||||||
|
_traceMessages.Enqueue(new MqttNetLogMessage("", DateTime.Now, -1,
|
||||||
|
"", MqttNetLogLevel.Info, "! DISCONNECTED EVENT FIRED", null));
|
||||||
|
|
||||||
|
Task.Run(UpdateLogAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConnected(object sender, MqttClientConnectedEventArgs e)
|
||||||
|
{
|
||||||
|
_traceMessages.Enqueue(new MqttNetLogMessage("", DateTime.Now, -1,
|
||||||
|
"", MqttNetLogLevel.Info, "! CONNECTED EVENT FIRED", null));
|
||||||
|
|
||||||
|
Task.Run(UpdateLogAsync);
|
||||||
|
}
|
||||||
|
|
||||||
private async void OnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs eventArgs)
|
private async void OnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
var item = $"Timestamp: {DateTime.Now:O} | Topic: {eventArgs.ApplicationMessage.Topic} | Payload: {Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload)} | QoS: {eventArgs.ApplicationMessage.QualityOfServiceLevel}";
|
var item = $"Timestamp: {DateTime.Now:O} | Topic: {eventArgs.ApplicationMessage.Topic} | Payload: {Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload)} | QoS: {eventArgs.ApplicationMessage.QualityOfServiceLevel}";
|
||||||
|
|||||||
Reference in New Issue
Block a user