diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 30406c39..1ff94d37 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -19,6 +19,7 @@ * [Client] Fixed a memory leak when web socket based connections trying to reconnect with an offline server. * [Client] Fixed a memory leak when TCP based connections trying to reconnect with an offline server. * [Client] Fixed an issue when connecting to an invalid host (format). +* [Client] Added support for user properties in CONNECT packet. * [ManagedClient] Added method to trigger PING/PONG manually (connection check etc.). * [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1. * [MQTTnet.AspNetCore] Fixed several packaging issues with the Nuget package. diff --git a/Source/MQTTnet/Client/Options/IMqttClientOptions.cs b/Source/MQTTnet/Client/Options/IMqttClientOptions.cs index 822603dc..ace8028b 100644 --- a/Source/MQTTnet/Client/Options/IMqttClientOptions.cs +++ b/Source/MQTTnet/Client/Options/IMqttClientOptions.cs @@ -1,6 +1,8 @@ -using System; -using MQTTnet.Client.ExtendedAuthenticationExchange; +using MQTTnet.Client.ExtendedAuthenticationExchange; using MQTTnet.Formatter; +using MQTTnet.Packets; +using System; +using System.Collections.Generic; namespace MQTTnet.Client.Options { @@ -12,11 +14,11 @@ namespace MQTTnet.Client.Options IMqttExtendedAuthenticationExchangeHandler ExtendedAuthenticationExchangeHandler { get; } MqttProtocolVersion ProtocolVersion { get; } IMqttClientChannelOptions ChannelOptions { get; } - + TimeSpan CommunicationTimeout { get; } TimeSpan KeepAlivePeriod { get; } TimeSpan? KeepAliveSendInterval { get; } - + MqttApplicationMessage WillMessage { get; } uint? WillDelayInterval { get; } @@ -28,5 +30,6 @@ namespace MQTTnet.Client.Options bool? RequestResponseInformation { get; } uint? SessionExpiryInterval { get; } ushort? TopicAliasMaximum { get; } + List UserProperties { get; set; } } } \ No newline at end of file diff --git a/Source/MQTTnet/Client/Options/MqttClientOptions.cs b/Source/MQTTnet/Client/Options/MqttClientOptions.cs index c47f5c6a..a28cbfd7 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptions.cs @@ -1,6 +1,8 @@ -using System; -using MQTTnet.Client.ExtendedAuthenticationExchange; +using MQTTnet.Client.ExtendedAuthenticationExchange; using MQTTnet.Formatter; +using MQTTnet.Packets; +using System; +using System.Collections.Generic; namespace MQTTnet.Client.Options { @@ -16,7 +18,7 @@ namespace MQTTnet.Client.Options public TimeSpan CommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10); public TimeSpan KeepAlivePeriod { get; set; } = TimeSpan.FromSeconds(15); public TimeSpan? KeepAliveSendInterval { get; set; } - + public MqttApplicationMessage WillMessage { get; set; } public uint? WillDelayInterval { get; set; } @@ -29,5 +31,6 @@ namespace MQTTnet.Client.Options public bool? RequestResponseInformation { get; set; } public uint? SessionExpiryInterval { get; set; } public ushort? TopicAliasMaximum { get; set; } + public List UserProperties { get; set; } } } diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs index 316e5b57..383dbc96 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs @@ -1,6 +1,8 @@ using MQTTnet.Client.ExtendedAuthenticationExchange; using MQTTnet.Formatter; +using MQTTnet.Packets; using System; +using System.Collections.Generic; using System.Linq; using System.Text; @@ -116,6 +118,20 @@ namespace MQTTnet.Client.Options return this; } + public MqttClientOptionsBuilder WithUserProperty(string name, string value) + { + if (name is null) throw new ArgumentNullException(nameof(name)); + if (value is null) throw new ArgumentNullException(nameof(value)); + + if (_options.UserProperties == null) + { + _options.UserProperties = new List(); + } + + _options.UserProperties.Add(new MqttUserProperty(name, value)); + return this; + } + public MqttClientOptionsBuilder WithCredentials(string username, string password = null) { byte[] passwordBuffer = null; diff --git a/Source/MQTTnet/Formatter/V5/MqttV500DataConverter.cs b/Source/MQTTnet/Formatter/V5/MqttV500DataConverter.cs index 886b937b..f55c3476 100644 --- a/Source/MQTTnet/Formatter/V5/MqttV500DataConverter.cs +++ b/Source/MQTTnet/Formatter/V5/MqttV500DataConverter.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using MQTTnet.Client.Connecting; +using MQTTnet.Client.Connecting; using MQTTnet.Client.Disconnecting; using MQTTnet.Client.Options; using MQTTnet.Client.Publishing; @@ -11,7 +8,9 @@ using MQTTnet.Exceptions; using MQTTnet.Packets; using MQTTnet.Protocol; using MQTTnet.Server; - +using System; +using System.Collections.Generic; +using System.Linq; using MqttClientSubscribeResult = MQTTnet.Client.Subscribing.MqttClientSubscribeResult; namespace MQTTnet.Formatter.V5 @@ -127,7 +126,8 @@ namespace MQTTnet.Formatter.V5 RequestProblemInformation = options.RequestProblemInformation, RequestResponseInformation = options.RequestResponseInformation, SessionExpiryInterval = options.SessionExpiryInterval, - TopicAliasMaximum = options.TopicAliasMaximum + TopicAliasMaximum = options.TopicAliasMaximum, + UserProperties = options.UserProperties } }; } @@ -244,11 +244,11 @@ namespace MQTTnet.Formatter.V5 { // QoS 0 has no response. So we treat it as a success always. // Both enums have the same values. So it can be easily converted. - result.ReasonCode = (MqttClientPublishReasonCode)pubAckPacket.ReasonCode; + result.ReasonCode = (MqttClientPublishReasonCode)pubAckPacket.ReasonCode; - result.PacketIdentifier = pubAckPacket.PacketIdentifier; + result.PacketIdentifier = pubAckPacket.PacketIdentifier; } - + return result; }