mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-19 19:13:11 +08:00
Compare commits
14
Commits
v3.0.0-rc2
...
v3.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac88f0a05a | ||
|
|
b02f30844c | ||
|
|
1a8bcae47c | ||
|
|
664549ab93 | ||
|
|
914d2b641f | ||
|
|
0cc0fcf5d9 | ||
|
|
5980cbd944 | ||
|
|
3ef7f60a18 | ||
|
|
efef23e3f5 | ||
|
|
53ab2ac140 | ||
|
|
2ecbd83d06 | ||
|
|
a278b6189b | ||
|
|
cdbdfdec6d | ||
|
|
808c2da5f6 |
@@ -34,10 +34,9 @@
|
|||||||
<!-- .NET Framework -->
|
<!-- .NET Framework -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\net452\MQTTnet.Extensions.ManagedClient.*" target="lib\net452\"/>
|
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\net452\MQTTnet.Extensions.ManagedClient.*" target="lib\net452\"/>
|
||||||
|
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net461\"/>
|
<!-- .NET Framework 4.6.0 will use binaries from 4.5.2. -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net462\"/>
|
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\net461\MQTTnet.Extensions.Rpc.*" target="lib\net461\"/>
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net470\"/>
|
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net471\"/>
|
<!-- Everything above .NET Framework 4.6.1 will use the binaries from 4.6.1. -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net472\"/>
|
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
|||||||
@@ -34,10 +34,9 @@
|
|||||||
<!-- .NET Framework -->
|
<!-- .NET Framework -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\net452\MQTTnet.Extensions.Rpc.*" target="lib\net452\"/>
|
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\net452\MQTTnet.Extensions.Rpc.*" target="lib\net452\"/>
|
||||||
|
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net461\"/>
|
<!-- .NET Framework 4.6.0 will use binaries from 4.5.2. -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net462\"/>
|
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\net461\MQTTnet.Extensions.Rpc.*" target="lib\net461\"/>
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net470\"/>
|
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net471\"/>
|
<!-- Everything above .NET Framework 4.6.1 will use the binaries from 4.6.1. -->
|
||||||
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net472\"/>
|
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
|||||||
+10
-39
@@ -11,36 +11,12 @@
|
|||||||
<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>
|
<releaseNotes>
|
||||||
* [Core] Added support for MQTTv5 packages.
|
* [Core] Fixed missing properties from PUBLISH packet in _MqttApplicationMessage_ (thanks to @pcbing).
|
||||||
* [Core] Performance improvements.
|
* [Core] Fixed wrong encoding of PUBREL and PUBCOMP packets for MQTTv5 (thanks to @perphilipp).
|
||||||
* [Core] Removed obsolete methods.
|
* [Client] Added the authentication result to the disconnected handler (only set when connecting failed).
|
||||||
* [Core] Fixed a memory leak when processing lots of messages (thanks to @tschanko)
|
* [Client] Added new overloads for _MqttClientOptionsBuilder_.
|
||||||
* [Core] Added more overloads for MQTT factory.
|
* [Server] Fixed a bug which returns wrong flag for existing session in CONNACK packet (thanks to @avengerstark).
|
||||||
* [Core] The client password is now hidden from the logs (replaced with **** if set).
|
* [nuget] .NET Framework builds are now using 4.5.2 or 4.6.1 builds instead of netstandard 2.0.
|
||||||
* [Core] Fixed a memory leak when using SSL connections (thanks to @biovoid).
|
|
||||||
* [Client] Added validation of topics before publishing.
|
|
||||||
* [Client] Added new MQTTv5 features to options builder.
|
|
||||||
* [Client] Added uniform API across all supported MQTT versions (BREAKING CHANGE!)
|
|
||||||
* [Client] The client will now avoid sending an ACK if an exception has been thrown in message handler (thanks to @ramonsmits).
|
|
||||||
* [Client] Fixed issues in QoS 2 handling which leads to message loss.
|
|
||||||
* [Client] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
|
|
||||||
* [Client] Added more configuration values to TCP endpoint options.
|
|
||||||
* [Client] Added used PacketIdentifier to publish result.
|
|
||||||
* [ManagedClient] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
|
|
||||||
* [ManagedClient] The log ID is now propagated to the internal client (thanks to @vbBerni).
|
|
||||||
* [ManagedClient] Added validation of topics before publishing.
|
|
||||||
* [ManagedClient] The internal MQTT client is now closed properly (thanks to @vbBerni).
|
|
||||||
* [Server] Added support for MQTTv5 clients. The server will still return _success_ for all cases at the moment even if more granular codes are available.
|
|
||||||
* [Server] Fixed issues in QoS 2 handling which leads to message loss.
|
|
||||||
* [Server] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
|
|
||||||
* [Server] The used logger instance is now propagated to the WebSocket server adapter.
|
|
||||||
* [Server] Added the flag "IsSecureConnection" which is set to true when the connection is encrypted.
|
|
||||||
* [Server] Fixed wrong will message behavior when stopping server (thanks to @JohBa)
|
|
||||||
* [Server] Added validation of topics before publishing.
|
|
||||||
* [Server] Added more configuration values to TCP endpoint options.
|
|
||||||
* [MQTTnet Server] Added as first Alpha version of standalone cross platform MQTT server.
|
|
||||||
|
|
||||||
* [Note] Due to MQTTv5 a lot of new classes were introduced. This required adding new namespaces as well. Most classes are backward compatible but new namespaces must be added.
|
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2019</copyright>
|
<copyright>Copyright Christian Kratky 2016-2019</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>
|
||||||
@@ -60,10 +36,6 @@
|
|||||||
<group targetFramework="uap10.0">
|
<group targetFramework="uap10.0">
|
||||||
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.8" />
|
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.8" />
|
||||||
</group>
|
</group>
|
||||||
<group targetFramework="net452">
|
|
||||||
</group>
|
|
||||||
<group targetFramework="net461">
|
|
||||||
</group>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|
||||||
@@ -83,10 +55,9 @@
|
|||||||
<!-- .NET Framework -->
|
<!-- .NET Framework -->
|
||||||
<file src="..\Source\MQTTnet\bin\Release\net452\MQTTnet.*" target="lib\net452\"/>
|
<file src="..\Source\MQTTnet\bin\Release\net452\MQTTnet.*" target="lib\net452\"/>
|
||||||
|
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net461\"/>
|
<!-- .NET Framework 4.6.0 will use binaries from 4.5.2. -->
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net462\"/>
|
<file src="..\Source\MQTTnet\bin\Release\net461\MQTTnet.*" target="lib\net461\"/>
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net470\"/>
|
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net471\"/>
|
<!-- Everything above .NET Framework 4.6.1 will use the binaries from 4.6.1. -->
|
||||||
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net472\"/>
|
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
@@ -1,17 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using MQTTnet.Client.Connecting;
|
||||||
|
|
||||||
namespace MQTTnet.Client.Disconnecting
|
namespace MQTTnet.Client.Disconnecting
|
||||||
{
|
{
|
||||||
public class MqttClientDisconnectedEventArgs : EventArgs
|
public class MqttClientDisconnectedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception)
|
public MqttClientDisconnectedEventArgs(bool clientWasConnected, Exception exception, MqttClientAuthenticateResult authenticateResult)
|
||||||
{
|
{
|
||||||
ClientWasConnected = clientWasConnected;
|
ClientWasConnected = clientWasConnected;
|
||||||
Exception = exception;
|
Exception = exception;
|
||||||
|
AuthenticateResult = authenticateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ClientWasConnected { get; }
|
public bool ClientWasConnected { get; }
|
||||||
|
|
||||||
public Exception Exception { get; }
|
public Exception Exception { get; }
|
||||||
|
|
||||||
|
public MqttClientAuthenticateResult AuthenticateResult { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
ThrowIfConnected("It is not allowed to connect with a server after the connection is established.");
|
ThrowIfConnected("It is not allowed to connect with a server after the connection is established.");
|
||||||
|
|
||||||
|
MqttClientAuthenticateResult authenticateResult = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Options = options;
|
Options = options;
|
||||||
@@ -81,7 +83,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
_packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken);
|
_packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken);
|
||||||
|
|
||||||
var authenticateResult = await AuthenticateAsync(adapter, options.WillMessage, cancellationToken).ConfigureAwait(false);
|
authenticateResult = await AuthenticateAsync(adapter, options.WillMessage, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
_sendTracker.Restart();
|
_sendTracker.Restart();
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(null, exception, authenticateResult).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
@@ -131,7 +133,7 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(null, null).ConfigureAwait(false);
|
await DisconnectInternalAsync(null, null, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +234,7 @@ namespace MQTTnet.Client
|
|||||||
if (IsConnected) throw new MqttProtocolViolationException(message);
|
if (IsConnected) throw new MqttProtocolViolationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DisconnectInternalAsync(Task sender, Exception exception)
|
private async Task DisconnectInternalAsync(Task sender, Exception exception, MqttClientAuthenticateResult authenticateResult)
|
||||||
{
|
{
|
||||||
var clientWasConnected = IsConnected;
|
var clientWasConnected = IsConnected;
|
||||||
|
|
||||||
@@ -267,7 +269,7 @@ namespace MQTTnet.Client
|
|||||||
var disconnectedHandler = DisconnectedHandler;
|
var disconnectedHandler = DisconnectedHandler;
|
||||||
if (disconnectedHandler != null)
|
if (disconnectedHandler != null)
|
||||||
{
|
{
|
||||||
await disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception)).ConfigureAwait(false);
|
await disconnectedHandler.HandleDisconnectedAsync(new MqttClientDisconnectedEventArgs(clientWasConnected, exception, authenticateResult)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,7 +378,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(_keepAlivePacketsSenderTask, exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(_keepAlivePacketsSenderTask, exception, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -404,7 +406,7 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(_packetReceiverTask, null).ConfigureAwait(false);
|
await DisconnectInternalAsync(_packetReceiverTask, null, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -436,7 +438,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(_packetReceiverTask, exception, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -497,7 +499,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
if (!DisconnectIsPending())
|
if (!DisconnectIsPending())
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
|
await DisconnectInternalAsync(_packetReceiverTask, exception, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,16 @@ namespace MQTTnet.Client.Options
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MqttClientOptionsBuilder WithTcpServer(Action<MqttClientTcpOptions> optionsBuilder)
|
||||||
|
{
|
||||||
|
if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder));
|
||||||
|
|
||||||
|
_tcpOptions = new MqttClientTcpOptions();
|
||||||
|
optionsBuilder.Invoke(_tcpOptions);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public MqttClientOptionsBuilder WithProxy(string address, string username = null, string password = null, string domain = null, bool bypassOnLocal = false, string[] bypassList = null)
|
public MqttClientOptionsBuilder WithProxy(string address, string username = null, string password = null, string domain = null, bool bypassOnLocal = false, string[] bypassList = null)
|
||||||
{
|
{
|
||||||
_proxyOptions = new MqttClientWebSocketProxyOptions
|
_proxyOptions = new MqttClientWebSocketProxyOptions
|
||||||
@@ -151,6 +161,15 @@ namespace MQTTnet.Client.Options
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MqttClientOptionsBuilder WithProxy(Action<MqttClientWebSocketProxyOptions> optionsBuilder)
|
||||||
|
{
|
||||||
|
if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder));
|
||||||
|
|
||||||
|
_proxyOptions = new MqttClientWebSocketProxyOptions();
|
||||||
|
optionsBuilder(_proxyOptions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public MqttClientOptionsBuilder WithWebSocketServer(string uri, MqttClientOptionsBuilderWebSocketParameters parameters = null)
|
public MqttClientOptionsBuilder WithWebSocketServer(string uri, MqttClientOptionsBuilderWebSocketParameters parameters = null)
|
||||||
{
|
{
|
||||||
_webSocketOptions = new MqttClientWebSocketOptions
|
_webSocketOptions = new MqttClientWebSocketOptions
|
||||||
@@ -163,9 +182,19 @@ namespace MQTTnet.Client.Options
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MqttClientOptionsBuilder WithWebSocketServer(Action<MqttClientWebSocketOptions> optionsBuilder)
|
||||||
|
{
|
||||||
|
if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder));
|
||||||
|
|
||||||
|
_webSocketOptions = new MqttClientWebSocketOptions();
|
||||||
|
optionsBuilder.Invoke(_webSocketOptions);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public MqttClientOptionsBuilder WithTls(MqttClientOptionsBuilderTlsParameters parameters)
|
public MqttClientOptionsBuilder WithTls(MqttClientOptionsBuilderTlsParameters parameters)
|
||||||
{
|
{
|
||||||
_tlsParameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
|
_tlsParameters = parameters;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +203,15 @@ namespace MQTTnet.Client.Options
|
|||||||
return WithTls(new MqttClientOptionsBuilderTlsParameters { UseTls = true });
|
return WithTls(new MqttClientOptionsBuilderTlsParameters { UseTls = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MqttClientOptionsBuilder WithTls(Action<MqttClientOptionsBuilderTlsParameters> optionsBuilder)
|
||||||
|
{
|
||||||
|
if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder));
|
||||||
|
|
||||||
|
_tlsParameters = new MqttClientOptionsBuilderTlsParameters();
|
||||||
|
optionsBuilder(_tlsParameters);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IMqttClientOptions Build()
|
public IMqttClientOptions Build()
|
||||||
{
|
{
|
||||||
if (_tcpOptions == null && _webSocketOptions == null)
|
if (_tcpOptions == null && _webSocketOptions == null)
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
|
|
||||||
return new MqttClientPublishResult
|
return new MqttClientPublishResult
|
||||||
{
|
{
|
||||||
|
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success
|
ReasonCode = MqttClientPublishReasonCode.Success
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ namespace MQTTnet.Formatter.V5
|
|||||||
Payload = publishPacket.Payload,
|
Payload = publishPacket.Payload,
|
||||||
QualityOfServiceLevel = publishPacket.QualityOfServiceLevel,
|
QualityOfServiceLevel = publishPacket.QualityOfServiceLevel,
|
||||||
Retain = publishPacket.Retain,
|
Retain = publishPacket.Retain,
|
||||||
|
ResponseTopic = publishPacket.Properties?.ResponseTopic,
|
||||||
|
ContentType = publishPacket.Properties?.ContentType,
|
||||||
|
CorrelationData = publishPacket.Properties?.CorrelationData,
|
||||||
|
MessageExpiryInterval = publishPacket.Properties?.MessageExpiryInterval,
|
||||||
|
SubscriptionIdentifier = publishPacket.Properties?.SubscriptionIdentifier,
|
||||||
|
TopicAlias = publishPacket.Properties?.TopicAlias,
|
||||||
|
PayloadFormatIndicator = publishPacket.Properties?.PayloadFormatIndicator,
|
||||||
UserProperties = publishPacket.Properties?.UserProperties ?? new List<MqttUserProperty>()
|
UserProperties = publishPacket.Properties?.UserProperties ?? new List<MqttUserProperty>()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -223,6 +230,7 @@ namespace MQTTnet.Formatter.V5
|
|||||||
{
|
{
|
||||||
return new MqttClientPublishResult
|
return new MqttClientPublishResult
|
||||||
{
|
{
|
||||||
|
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
||||||
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError,
|
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError,
|
||||||
ReasonString = pubCompPacket.Properties?.ReasonString,
|
ReasonString = pubCompPacket.Properties?.ReasonString,
|
||||||
UserProperties = pubCompPacket.Properties?.UserProperties
|
UserProperties = pubCompPacket.Properties?.UserProperties
|
||||||
@@ -231,6 +239,7 @@ namespace MQTTnet.Formatter.V5
|
|||||||
|
|
||||||
var result = new MqttClientPublishResult
|
var result = new MqttClientPublishResult
|
||||||
{
|
{
|
||||||
|
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success,
|
ReasonCode = MqttClientPublishReasonCode.Success,
|
||||||
ReasonString = pubCompPacket.Properties?.ReasonString,
|
ReasonString = pubCompPacket.Properties?.ReasonString,
|
||||||
UserProperties = pubCompPacket.Properties?.UserProperties
|
UserProperties = pubCompPacket.Properties?.UserProperties
|
||||||
|
|||||||
@@ -343,9 +343,6 @@ namespace MQTTnet.Formatter.V5
|
|||||||
ThrowReasonCodeNotSetException();
|
ThrowReasonCodeNotSetException();
|
||||||
}
|
}
|
||||||
|
|
||||||
packetWriter.Write(packet.PacketIdentifier.Value);
|
|
||||||
packetWriter.Write((byte)packet.ReasonCode.Value);
|
|
||||||
|
|
||||||
var propertiesWriter = new MqttV500PropertiesWriter();
|
var propertiesWriter = new MqttV500PropertiesWriter();
|
||||||
if (packet.Properties != null)
|
if (packet.Properties != null)
|
||||||
{
|
{
|
||||||
@@ -353,7 +350,9 @@ namespace MQTTnet.Formatter.V5
|
|||||||
propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
|
propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packetWriter.Length > 0 || packet.ReasonCode.Value != MqttPubRelReasonCode.Success)
|
packetWriter.Write(packet.PacketIdentifier.Value);
|
||||||
|
|
||||||
|
if (propertiesWriter.Length > 0 || packet.ReasonCode.Value != MqttPubRelReasonCode.Success)
|
||||||
{
|
{
|
||||||
packetWriter.Write((byte)packet.ReasonCode.Value);
|
packetWriter.Write((byte)packet.ReasonCode.Value);
|
||||||
propertiesWriter.WriteToPacket(packetWriter);
|
propertiesWriter.WriteToPacket(packetWriter);
|
||||||
@@ -372,7 +371,6 @@ namespace MQTTnet.Formatter.V5
|
|||||||
}
|
}
|
||||||
|
|
||||||
packetWriter.Write(packet.PacketIdentifier.Value);
|
packetWriter.Write(packet.PacketIdentifier.Value);
|
||||||
packetWriter.Write((byte)packet.ReasonCode.Value);
|
|
||||||
|
|
||||||
var propertiesWriter = new MqttV500PropertiesWriter();
|
var propertiesWriter = new MqttV500PropertiesWriter();
|
||||||
if (packet.Properties != null)
|
if (packet.Properties != null)
|
||||||
@@ -381,7 +379,7 @@ namespace MQTTnet.Formatter.V5
|
|||||||
propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
|
propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packetWriter.Length > 0 || packet.ReasonCode.Value != MqttPubCompReasonCode.Success)
|
if (propertiesWriter.Length > 0 || packet.ReasonCode.Value != MqttPubCompReasonCode.Success)
|
||||||
{
|
{
|
||||||
packetWriter.Write((byte)packet.ReasonCode.Value);
|
packetWriter.Write((byte)packet.ReasonCode.Value);
|
||||||
propertiesWriter.WriteToPacket(packetWriter);
|
propertiesWriter.WriteToPacket(packetWriter);
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ namespace MQTTnet.Formatter.V5
|
|||||||
{
|
{
|
||||||
public class MqttV500PropertiesWriter
|
public class MqttV500PropertiesWriter
|
||||||
{
|
{
|
||||||
|
// TODO: Consider lazy init on first write to avoid useless allocations.
|
||||||
private readonly MqttPacketWriter _packetWriter = new MqttPacketWriter();
|
private readonly MqttPacketWriter _packetWriter = new MqttPacketWriter();
|
||||||
|
|
||||||
|
public int Length => _packetWriter.Length;
|
||||||
|
|
||||||
public void WriteUserProperties(List<MqttUserProperty> userProperties)
|
public void WriteUserProperties(List<MqttUserProperty> userProperties)
|
||||||
{
|
{
|
||||||
if (userProperties == null || userProperties.Count == 0)
|
if (userProperties == null || userProperties.Count == 0)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
ReturnCode = MqttConnectReturnCode.ConnectionAccepted,
|
ReturnCode = MqttConnectReturnCode.ConnectionAccepted,
|
||||||
ReasonCode = MqttConnectReasonCode.Success,
|
ReasonCode = MqttConnectReasonCode.Success,
|
||||||
IsSessionPresent = Session.IsCleanSession
|
IsSessionPresent = !Session.IsCleanSession
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
Session.IsCleanSession = false;
|
Session.IsCleanSession = false;
|
||||||
|
|||||||
@@ -61,8 +61,9 @@ namespace MQTTnet.Server
|
|||||||
using (await _messagesLock.WaitAsync().ConfigureAwait(false))
|
using (await _messagesLock.WaitAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var saveIsRequired = false;
|
var saveIsRequired = false;
|
||||||
|
var hasPayload = applicationMessage.Payload != null && applicationMessage.Payload.Length > 0;
|
||||||
|
|
||||||
if (applicationMessage.Payload?.Any() != true)
|
if (!hasPayload)
|
||||||
{
|
{
|
||||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||||
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using MQTTnet.Client.Disconnecting;
|
|||||||
using MQTTnet.Client.Options;
|
using MQTTnet.Client.Options;
|
||||||
using MQTTnet.Client.Subscribing;
|
using MQTTnet.Client.Subscribing;
|
||||||
using MQTTnet.Exceptions;
|
using MQTTnet.Exceptions;
|
||||||
using MQTTnet.Formatter;
|
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
using MQTTnet.Tests.Mockups;
|
using MQTTnet.Tests.Mockups;
|
||||||
@@ -21,6 +20,34 @@ namespace MQTTnet.Tests
|
|||||||
[TestClass]
|
[TestClass]
|
||||||
public class Client_Tests
|
public class Client_Tests
|
||||||
{
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public async Task PacketIdentifier_In_Publish_Result()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = new TestEnvironment())
|
||||||
|
{
|
||||||
|
await testEnvironment.StartServerAsync();
|
||||||
|
var client = await testEnvironment.ConnectClientAsync();
|
||||||
|
|
||||||
|
var result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.AtMostOnce);
|
||||||
|
Assert.AreEqual(null, result.PacketIdentifier);
|
||||||
|
|
||||||
|
result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.AtMostOnce);
|
||||||
|
Assert.AreEqual(null, result.PacketIdentifier);
|
||||||
|
|
||||||
|
result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||||
|
Assert.AreEqual((ushort)1, result.PacketIdentifier);
|
||||||
|
|
||||||
|
result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||||
|
Assert.AreEqual((ushort)2, result.PacketIdentifier);
|
||||||
|
|
||||||
|
result = await client.PublishAsync("a", "a", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||||
|
Assert.AreEqual((ushort)3, result.PacketIdentifier);
|
||||||
|
|
||||||
|
result = await client.PublishAsync("b", "b", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||||
|
Assert.AreEqual((ushort)4, result.PacketIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Invalid_Connect_Throws_Exception()
|
public async Task Invalid_Connect_Throws_Exception()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ namespace MQTTnet.Tests
|
|||||||
public async Task Dispose_Channel_While_Used()
|
public async Task Dispose_Channel_While_Used()
|
||||||
{
|
{
|
||||||
var ct = new CancellationTokenSource();
|
var ct = new CancellationTokenSource();
|
||||||
|
var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 50001));
|
||||||
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 50000));
|
|
||||||
serverSocket.Listen(0);
|
serverSocket.Listen(0);
|
||||||
|
|
||||||
#pragma warning disable 4014
|
#pragma warning disable 4014
|
||||||
@@ -35,7 +35,7 @@ namespace MQTTnet.Tests
|
|||||||
}, ct.Token);
|
}, ct.Token);
|
||||||
|
|
||||||
var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
await clientSocket.ConnectAsync(IPAddress.Loopback, 50000);
|
await clientSocket.ConnectAsync(IPAddress.Loopback, 50001);
|
||||||
|
|
||||||
await Task.Delay(100, ct.Token);
|
await Task.Delay(100, ct.Token);
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@ namespace MQTTnet.Tests
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ct.Cancel(false);
|
ct.Cancel(false);
|
||||||
|
serverSocket.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,20 @@ namespace MQTTnet.Tests
|
|||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task Use_Clean_Session()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = new TestEnvironment())
|
||||||
|
{
|
||||||
|
await testEnvironment.StartServerAsync();
|
||||||
|
|
||||||
|
var client = testEnvironment.CreateClient();
|
||||||
|
var connectResult = await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort).WithCleanSession().Build());
|
||||||
|
|
||||||
|
Assert.IsFalse(connectResult.IsSessionPresent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Will_Message_Do_Not_Send()
|
public async Task Will_Message_Do_Not_Send()
|
||||||
{
|
{
|
||||||
@@ -61,7 +75,7 @@ namespace MQTTnet.Tests
|
|||||||
{
|
{
|
||||||
var receivedMessagesCount = 0;
|
var receivedMessagesCount = 0;
|
||||||
|
|
||||||
await testEnvironment.StartServerAsync(new MqttServerOptionsBuilder());
|
await testEnvironment.StartServerAsync();
|
||||||
|
|
||||||
var willMessage = new MqttApplicationMessageBuilder().WithTopic("My/last/will").WithAtMostOnceQoS().Build();
|
var willMessage = new MqttApplicationMessageBuilder().WithTopic("My/last/will").WithAtMostOnceQoS().Build();
|
||||||
|
|
||||||
@@ -540,7 +554,7 @@ namespace MQTTnet.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Clear_Retained_Message()
|
public async Task Clear_Retained_Message_With_Empty_Payload()
|
||||||
{
|
{
|
||||||
using (var testEnvironment = new TestEnvironment())
|
using (var testEnvironment = new TestEnvironment())
|
||||||
{
|
{
|
||||||
@@ -567,6 +581,34 @@ namespace MQTTnet.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task Clear_Retained_Message_With_Null_Payload()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = new TestEnvironment())
|
||||||
|
{
|
||||||
|
var receivedMessagesCount = 0;
|
||||||
|
|
||||||
|
await testEnvironment.StartServerAsync();
|
||||||
|
|
||||||
|
var c1 = await testEnvironment.ConnectClientAsync();
|
||||||
|
|
||||||
|
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
|
||||||
|
await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload((byte[])null).WithRetainFlag().Build());
|
||||||
|
|
||||||
|
await c1.DisconnectAsync();
|
||||||
|
|
||||||
|
var c2 = await testEnvironment.ConnectClientAsync();
|
||||||
|
|
||||||
|
c2.UseApplicationMessageReceivedHandler(c => Interlocked.Increment(ref receivedMessagesCount));
|
||||||
|
|
||||||
|
await Task.Delay(200);
|
||||||
|
await c2.SubscribeAsync(new TopicFilter { Topic = "retained", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce });
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, receivedMessagesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task Intercept_Application_Message()
|
public async Task Intercept_Application_Message()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
@@ -118,4 +120,22 @@ namespace MQTTnet.TestApp.NetCore
|
|||||||
return Task.FromResult(retainedMessages);
|
return Task.FromResult(retainedMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WikiCode
|
||||||
|
{
|
||||||
|
public void Code()
|
||||||
|
{
|
||||||
|
//Validate certificate.
|
||||||
|
var options = new MqttClientOptionsBuilder()
|
||||||
|
.WithTls(new MqttClientOptionsBuilderTlsParameters
|
||||||
|
{
|
||||||
|
CertificateValidationCallback = (X509Certificate x, X509Chain y, SslPolicyErrors z, IMqttClientOptions o) =>
|
||||||
|
{
|
||||||
|
// TODO: Check conditions of certificate by using above parameters.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Windows.Security.Cryptography.Certificates;
|
using Windows.Security.Cryptography.Certificates;
|
||||||
@@ -714,6 +716,25 @@ namespace MQTTnet.TestApp.UniversalWindows
|
|||||||
var mqttServer = new MqttFactory().CreateMqttServer();
|
var mqttServer = new MqttFactory().CreateMqttServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Setup subscription interceptor.
|
||||||
|
var options = new MqttServerOptionsBuilder()
|
||||||
|
.WithSubscriptionInterceptor(context =>
|
||||||
|
{
|
||||||
|
if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
|
||||||
|
{
|
||||||
|
context.AcceptSubscription = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
|
||||||
|
{
|
||||||
|
context.AcceptSubscription = false;
|
||||||
|
context.CloseConnection = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Setup and start a managed MQTT client.
|
// Setup and start a managed MQTT client.
|
||||||
var options = new ManagedMqttClientOptionsBuilder()
|
var options = new ManagedMqttClientOptionsBuilder()
|
||||||
|
|||||||
+1
-1
@@ -14,5 +14,5 @@ build:
|
|||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- cmd: dotnet vstest "%APPVEYOR_BUILD_FOLDER%\Tests\MQTTnet.Core.Tests\bin\Release\netcoreapp2.1\MQTTnet.Core.Tests.dll"
|
- cmd: dotnet vstest "%APPVEYOR_BUILD_FOLDER%\Tests\MQTTnet.Core.Tests\bin\Release\netcoreapp2.1\MQTTnet.Tests.dll"
|
||||||
- cmd: dotnet vstest "%APPVEYOR_BUILD_FOLDER%\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp2.1\MQTTnet.AspNetCore.Tests.dll"
|
- cmd: dotnet vstest "%APPVEYOR_BUILD_FOLDER%\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp2.1\MQTTnet.AspNetCore.Tests.dll"
|
||||||
|
|||||||
Reference in New Issue
Block a user