Compare commits

...
8 Commits
11 changed files with 90 additions and 69 deletions
@@ -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>
+4 -5
View File
@@ -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
View File
@@ -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; }
} }
} }
+11 -9
View File
@@ -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)
@@ -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>()
}; };
} }
@@ -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,8 +371,7 @@ 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;
+1 -1
View File
@@ -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"