mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-29 18:02:48 +08:00
Remove obsolete data converter.
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
* [Core] Removed global logger and refactored logging (BREAKING CHANGE!).
|
* [Core] Removed global logger and refactored logging (BREAKING CHANGE!).
|
||||||
* [Client] Renamed _MqttClientConnectResult_ to _MqttClientConnectResult_ (BREAKING CHANGE!).
|
* [Client] Renamed _MqttClientConnectResult_ to _MqttClientConnectResult_ (BREAKING CHANGE!).
|
||||||
* [Client] The OS will now choose the best TLS version to use. It is no longer fixed to 1.3 etc. (thanks to @patagonaa, #1271).
|
* [Client] The OS will now choose the best TLS version to use. It is no longer fixed to 1.3 etc. (thanks to @patagonaa, #1271).
|
||||||
|
* [Client] Exposed user properties and reason string in subscribe result.
|
||||||
|
* [Client] Exposed user properties and reason string in unsubscribe result.
|
||||||
* [ManagedClient] Extended ReconnectAsync (thanks to @nvsnkv, #1202).
|
* [ManagedClient] Extended ReconnectAsync (thanks to @nvsnkv, #1202).
|
||||||
* [ManagedClient] Improved Amazon AWS support (thanks to @scottbrogden-iheartmedia, #1209).
|
* [ManagedClient] Improved Amazon AWS support (thanks to @scottbrogden-iheartmedia, #1209).
|
||||||
* [ManagedClient] Fixed bug that allowed invalid subscriptions (Thanks to @marcelwinh).
|
* [ManagedClient] Fixed bug that allowed invalid subscriptions (Thanks to @marcelwinh).
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using MQTTnet.Exceptions;
|
||||||
|
using MQTTnet.Formatter;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Protocol;
|
||||||
|
|
||||||
|
namespace MQTTnet.Client.Connecting
|
||||||
|
{
|
||||||
|
public sealed class MqttClientConnectResultFactory
|
||||||
|
{
|
||||||
|
public MqttClientConnectResult Create(MqttConnAckPacket connAckPacket, MqttProtocolVersion protocolVersion)
|
||||||
|
{
|
||||||
|
if (connAckPacket == null) throw new ArgumentNullException(nameof(connAckPacket));
|
||||||
|
|
||||||
|
if (protocolVersion == MqttProtocolVersion.V500)
|
||||||
|
{
|
||||||
|
return CreateForMqtt500(connAckPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateForMqtt311(connAckPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MqttClientConnectResult CreateForMqtt500(MqttConnAckPacket connAckPacket)
|
||||||
|
{
|
||||||
|
if (connAckPacket == null) throw new ArgumentNullException(nameof(connAckPacket));
|
||||||
|
|
||||||
|
return new MqttClientConnectResult
|
||||||
|
{
|
||||||
|
IsSessionPresent = connAckPacket.IsSessionPresent,
|
||||||
|
ResultCode = (MqttClientConnectResultCode) (int) connAckPacket.ReasonCode,
|
||||||
|
WildcardSubscriptionAvailable = connAckPacket.Properties.WildcardSubscriptionAvailable,
|
||||||
|
RetainAvailable = connAckPacket.Properties.RetainAvailable,
|
||||||
|
AssignedClientIdentifier = connAckPacket.Properties.AssignedClientIdentifier,
|
||||||
|
AuthenticationMethod = connAckPacket.Properties.AuthenticationMethod,
|
||||||
|
AuthenticationData = connAckPacket.Properties.AuthenticationData,
|
||||||
|
MaximumPacketSize = connAckPacket.Properties.MaximumPacketSize,
|
||||||
|
ReasonString = connAckPacket.Properties.ReasonString,
|
||||||
|
ReceiveMaximum = connAckPacket.Properties.ReceiveMaximum,
|
||||||
|
MaximumQoS = connAckPacket.Properties.MaximumQoS ?? MqttQualityOfServiceLevel.ExactlyOnce,
|
||||||
|
ResponseInformation = connAckPacket.Properties.ResponseInformation,
|
||||||
|
TopicAliasMaximum = connAckPacket.Properties.TopicAliasMaximum,
|
||||||
|
ServerReference = connAckPacket.Properties.ServerReference,
|
||||||
|
ServerKeepAlive = connAckPacket.Properties.ServerKeepAlive,
|
||||||
|
SessionExpiryInterval = connAckPacket.Properties?.SessionExpiryInterval,
|
||||||
|
SubscriptionIdentifiersAvailable = connAckPacket.Properties.SubscriptionIdentifiersAvailable,
|
||||||
|
SharedSubscriptionAvailable = connAckPacket.Properties.SharedSubscriptionAvailable,
|
||||||
|
UserProperties = connAckPacket.Properties.UserProperties
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static MqttClientConnectResult CreateForMqtt311(MqttConnAckPacket connAckPacket)
|
||||||
|
{
|
||||||
|
if (connAckPacket == null) throw new ArgumentNullException(nameof(connAckPacket));
|
||||||
|
|
||||||
|
return new MqttClientConnectResult
|
||||||
|
{
|
||||||
|
RetainAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
|
||||||
|
WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
|
||||||
|
IsSessionPresent = connAckPacket.IsSessionPresent,
|
||||||
|
ResultCode = ConvertReturnCodeToResultCode(connAckPacket.ReturnCode)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static MqttClientConnectResultCode ConvertReturnCodeToResultCode(MqttConnectReturnCode connectReturnCode)
|
||||||
|
{
|
||||||
|
switch (connectReturnCode)
|
||||||
|
{
|
||||||
|
case MqttConnectReturnCode.ConnectionAccepted:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.UnsupportedProtocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MqttConnectReturnCode.ConnectionRefusedNotAuthorized:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.NotAuthorized;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.BadUserNameOrPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.ClientIdentifierNotValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MqttConnectReturnCode.ConnectionRefusedServerUnavailable:
|
||||||
|
{
|
||||||
|
return MqttClientConnectResultCode.ServerUnavailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new MqttProtocolViolationException("Received unexpected return code.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -92,10 +92,10 @@ namespace MQTTnet.Client
|
|||||||
var adapter = _adapterFactory.CreateClientAdapter(options);
|
var adapter = _adapterFactory.CreateClientAdapter(options);
|
||||||
_adapter = adapter;
|
_adapter = adapter;
|
||||||
|
|
||||||
using (var combined = CancellationTokenSource.CreateLinkedTokenSource(backgroundCancellationToken, cancellationToken))
|
using (var effectiveCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(backgroundCancellationToken, cancellationToken))
|
||||||
{
|
{
|
||||||
_logger.Verbose("Trying to connect with server '{0}' (Timeout={1}).", options.ChannelOptions, options.CommunicationTimeout);
|
_logger.Verbose("Trying to connect with server '{0}' (Timeout={1}).", options.ChannelOptions, options.CommunicationTimeout);
|
||||||
await adapter.ConnectAsync(options.CommunicationTimeout, combined.Token).ConfigureAwait(false);
|
await adapter.ConnectAsync(options.CommunicationTimeout, effectiveCancellationToken.Token).ConfigureAwait(false);
|
||||||
_logger.Verbose("Connection with server established.");
|
_logger.Verbose("Connection with server established.");
|
||||||
|
|
||||||
_publishPacketReceiverQueue = new AsyncQueue<MqttPublishPacket>();
|
_publishPacketReceiverQueue = new AsyncQueue<MqttPublishPacket>();
|
||||||
@@ -103,7 +103,7 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
_packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken);
|
_packetReceiverTask = Task.Run(() => TryReceivePacketsAsync(backgroundCancellationToken), backgroundCancellationToken);
|
||||||
|
|
||||||
connectResult = await AuthenticateAsync(adapter, options.WillMessage, combined.Token).ConfigureAwait(false);
|
connectResult = await AuthenticateAsync(options, effectiveCancellationToken.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastPacketSentTimestamp = DateTime.UtcNow;
|
_lastPacketSentTimestamp = DateTime.UtcNow;
|
||||||
@@ -212,7 +212,9 @@ namespace MQTTnet.Client
|
|||||||
subscribePacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
subscribePacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
||||||
|
|
||||||
var subAckPacket = await SendAndReceiveAsync<MqttSubAckPacket>(subscribePacket, cancellationToken).ConfigureAwait(false);
|
var subAckPacket = await SendAndReceiveAsync<MqttSubAckPacket>(subscribePacket, cancellationToken).ConfigureAwait(false);
|
||||||
return _adapter.PacketFormatterAdapter.DataConverter.CreateClientSubscribeResult(subscribePacket, subAckPacket);
|
|
||||||
|
var clientSubscribeResultFactory = new MqttClientSubscribeResultFactory();
|
||||||
|
return clientSubscribeResultFactory.Create(subscribePacket, subAckPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MqttClientUnsubscribeResult> UnsubscribeAsync(MqttClientUnsubscribeOptions options, CancellationToken cancellationToken)
|
public async Task<MqttClientUnsubscribeResult> UnsubscribeAsync(MqttClientUnsubscribeOptions options, CancellationToken cancellationToken)
|
||||||
@@ -227,7 +229,9 @@ namespace MQTTnet.Client
|
|||||||
unsubscribePacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
unsubscribePacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
||||||
|
|
||||||
var unsubAckPacket = await SendAndReceiveAsync<MqttUnsubAckPacket>(unsubscribePacket, cancellationToken).ConfigureAwait(false);
|
var unsubAckPacket = await SendAndReceiveAsync<MqttUnsubAckPacket>(unsubscribePacket, cancellationToken).ConfigureAwait(false);
|
||||||
return _adapter.PacketFormatterAdapter.DataConverter.CreateClientUnsubscribeResult(unsubscribePacket, unsubAckPacket);
|
|
||||||
|
var clientUnsubscribeResultFactory = new MqttClientUnsubscribeResultFactory();
|
||||||
|
return clientUnsubscribeResultFactory.Create(unsubscribePacket, unsubAckPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
|
public Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
|
||||||
@@ -293,17 +297,19 @@ namespace MQTTnet.Client
|
|||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttClientConnectResult> AuthenticateAsync(IMqttChannelAdapter channelAdapter, MqttApplicationMessage willApplicationMessage, CancellationToken cancellationToken)
|
async Task<MqttClientConnectResult> AuthenticateAsync(IMqttClientOptions options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
MqttClientConnectResult result;
|
MqttClientConnectResult result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var connectPacketFactory = new MqttConnectPacketFactory();
|
var connectPacketFactory = new MqttConnectPacketFactory();
|
||||||
var connectPacket = connectPacketFactory.Create(Options);
|
var connectPacket = connectPacketFactory.Create(options);
|
||||||
|
|
||||||
var connAckPacket = await SendAndReceiveAsync<MqttConnAckPacket>(connectPacket, cancellationToken).ConfigureAwait(false);
|
var connAckPacket = await SendAndReceiveAsync<MqttConnAckPacket>(connectPacket, cancellationToken).ConfigureAwait(false);
|
||||||
result = channelAdapter.PacketFormatterAdapter.DataConverter.CreateClientConnectResult(connAckPacket);
|
|
||||||
|
var clientConnectResultFactory = new MqttClientConnectResultFactory();
|
||||||
|
result = clientConnectResultFactory.Create(connAckPacket, options.ProtocolVersion);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -708,7 +714,8 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
// The packet is unknown. Probably due to a restart of the client.
|
// The packet is unknown. Probably due to a restart of the client.
|
||||||
// So wen send this to the server to trigger a full resend of the message.
|
// So wen send this to the server to trigger a full resend of the message.
|
||||||
var pubRelPacket = _adapter.PacketFormatterAdapter.DataConverter.CreatePubRelPacket(pubRecPacket, MqttApplicationMessageReceivedReasonCode.PacketIdentifierNotFound);
|
var pubRelPacketFactory = new MqttPubRelPacketFactory();
|
||||||
|
var pubRelPacket = pubRelPacketFactory.Create(pubRecPacket, MqttApplicationMessageReceivedReasonCode.PacketIdentifierNotFound);
|
||||||
return SendAsync(pubRelPacket, cancellationToken);
|
return SendAsync(pubRelPacket, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,7 +724,8 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var pubCompPacket = _adapter.PacketFormatterAdapter.DataConverter.CreatePubCompPacket(pubRelPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
var pubCompPacketFactory = new MqttPubCompPacketFactory();
|
||||||
|
var pubCompPacket =pubCompPacketFactory.Create(pubRelPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
return SendAsync(pubCompPacket, cancellationToken);
|
return SendAsync(pubCompPacket, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,7 +754,8 @@ namespace MQTTnet.Client
|
|||||||
{
|
{
|
||||||
// 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(publishPacket, cancellationToken).ConfigureAwait(false);
|
await SendAsync(publishPacket, cancellationToken).ConfigureAwait(false);
|
||||||
return _adapter.PacketFormatterAdapter.DataConverter.CreateClientPublishResult(null);
|
|
||||||
|
return new MqttClientPublishResultFactory().Create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttClientPublishResult> PublishAtLeastOnceAsync(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
async Task<MqttClientPublishResult> PublishAtLeastOnceAsync(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||||
@@ -754,8 +763,9 @@ namespace MQTTnet.Client
|
|||||||
publishPacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
publishPacket.PacketIdentifier = _packetIdentifierProvider.GetNextPacketIdentifier();
|
||||||
|
|
||||||
var pubAckPacket = await SendAndReceiveAsync<MqttPubAckPacket>(publishPacket, cancellationToken).ConfigureAwait(false);
|
var pubAckPacket = await SendAndReceiveAsync<MqttPubAckPacket>(publishPacket, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return _adapter.PacketFormatterAdapter.DataConverter.CreateClientPublishResult(pubAckPacket);
|
var clientPublishResultFactory = new MqttClientPublishResultFactory();
|
||||||
|
return clientPublishResultFactory.Create(pubAckPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttClientPublishResult> PublishExactlyOnceAsync(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
async Task<MqttClientPublishResult> PublishExactlyOnceAsync(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||||
@@ -764,11 +774,13 @@ namespace MQTTnet.Client
|
|||||||
|
|
||||||
var pubRecPacket = await SendAndReceiveAsync<MqttPubRecPacket>(publishPacket, cancellationToken).ConfigureAwait(false);
|
var pubRecPacket = await SendAndReceiveAsync<MqttPubRecPacket>(publishPacket, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var pubRelPacket = _adapter.PacketFormatterAdapter.DataConverter.CreatePubRelPacket(pubRecPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
var pubRelPacketFactory = new MqttPubRelPacketFactory();
|
||||||
|
var pubRelPacket = pubRelPacketFactory.Create(pubRecPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
|
|
||||||
var pubCompPacket = await SendAndReceiveAsync<MqttPubCompPacket>(pubRelPacket, cancellationToken).ConfigureAwait(false);
|
var pubCompPacket = await SendAndReceiveAsync<MqttPubCompPacket>(pubRelPacket, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
return _adapter.PacketFormatterAdapter.DataConverter.CreateClientPublishResult(pubRecPacket, pubCompPacket);
|
var clientPublishResultFactory = new MqttClientPublishResultFactory();
|
||||||
|
return clientPublishResultFactory.Create(pubRecPacket, pubCompPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttApplicationMessageReceivedEventArgs> HandleReceivedApplicationMessageAsync(MqttPublishPacket publishPacket)
|
async Task<MqttApplicationMessageReceivedEventArgs> HandleReceivedApplicationMessageAsync(MqttPublishPacket publishPacket)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
public enum MqttClientPublishReasonCode
|
public enum MqttClientPublishReasonCode
|
||||||
{
|
{
|
||||||
Success = 0,
|
Success = 0,
|
||||||
|
|
||||||
NoMatchingSubscribers = 16,
|
NoMatchingSubscribers = 16,
|
||||||
UnspecifiedError = 128,
|
UnspecifiedError = 128,
|
||||||
ImplementationSpecificError = 131,
|
ImplementationSpecificError = 131,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using MQTTnet.Packets;
|
|||||||
|
|
||||||
namespace MQTTnet.Client.Publishing
|
namespace MQTTnet.Client.Publishing
|
||||||
{
|
{
|
||||||
public class MqttClientPublishResult
|
public sealed class MqttClientPublishResult
|
||||||
{
|
{
|
||||||
public ushort? PacketIdentifier { get; set; }
|
public ushort? PacketIdentifier { get; set; }
|
||||||
|
|
||||||
@@ -27,6 +27,6 @@ namespace MQTTnet.Client.Publishing
|
|||||||
/// The feature is very similar to the HTTP header concept.
|
/// The feature is very similar to the HTTP header concept.
|
||||||
/// Hint: MQTT 5 feature only.
|
/// Hint: MQTT 5 feature only.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<MqttUserProperty> UserProperties { get; set; }
|
public List<MqttUserProperty> UserProperties { get; } = new List<MqttUserProperty>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Protocol;
|
||||||
|
|
||||||
|
namespace MQTTnet.Client.Publishing
|
||||||
|
{
|
||||||
|
public sealed class MqttClientPublishResultFactory
|
||||||
|
{
|
||||||
|
public MqttClientPublishResult Create(MqttPubAckPacket pubAckPacket)
|
||||||
|
{
|
||||||
|
var result = new MqttClientPublishResult
|
||||||
|
{
|
||||||
|
ReasonCode = MqttClientPublishReasonCode.Success,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pubAckPacket != null)
|
||||||
|
{
|
||||||
|
result.ReasonString = pubAckPacket.Properties.ReasonString;
|
||||||
|
result.UserProperties.AddRange(pubAckPacket.Properties.UserProperties);
|
||||||
|
|
||||||
|
// 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) (int) pubAckPacket.ReasonCode;
|
||||||
|
|
||||||
|
result.PacketIdentifier = pubAckPacket.PacketIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MqttClientPublishResult Create(MqttPubRecPacket pubRecPacket, MqttPubCompPacket pubCompPacket)
|
||||||
|
{
|
||||||
|
if (pubRecPacket == null || pubCompPacket == null)
|
||||||
|
{
|
||||||
|
return new MqttClientPublishResult
|
||||||
|
{
|
||||||
|
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
MqttClientPublishResult result;
|
||||||
|
|
||||||
|
// The PUBCOMP is the last packet in QoS 2. So we use the results from that instead of PUBREC.
|
||||||
|
if (pubCompPacket.ReasonCode == MqttPubCompReasonCode.PacketIdentifierNotFound)
|
||||||
|
{
|
||||||
|
result = new MqttClientPublishResult
|
||||||
|
{
|
||||||
|
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
||||||
|
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError,
|
||||||
|
ReasonString = pubCompPacket.Properties.ReasonString
|
||||||
|
};
|
||||||
|
|
||||||
|
result.UserProperties.AddRange(pubCompPacket.Properties.UserProperties);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new MqttClientPublishResult
|
||||||
|
{
|
||||||
|
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
||||||
|
ReasonCode = MqttClientPublishReasonCode.Success,
|
||||||
|
ReasonString = pubCompPacket.Properties.ReasonString
|
||||||
|
};
|
||||||
|
|
||||||
|
result.UserProperties.AddRange(pubCompPacket.Properties.UserProperties);
|
||||||
|
|
||||||
|
if (pubRecPacket.ReasonCode != MqttPubRecReasonCode.Success)
|
||||||
|
{
|
||||||
|
// Both enums share the same values.
|
||||||
|
result.ReasonCode = (MqttClientPublishReasonCode) pubRecPacket.ReasonCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ using MQTTnet.Packets;
|
|||||||
|
|
||||||
namespace MQTTnet.Client.Subscribing
|
namespace MQTTnet.Client.Subscribing
|
||||||
{
|
{
|
||||||
public class MqttClientSubscribeOptions
|
public sealed class MqttClientSubscribeOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a list of topic filters the client wants to subscribe to.
|
/// Gets or sets a list of topic filters the client wants to subscribe to.
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
|
||||||
namespace MQTTnet.Client.Subscribing
|
namespace MQTTnet.Client.Subscribing
|
||||||
{
|
{
|
||||||
public class MqttClientSubscribeResult
|
public sealed class MqttClientSubscribeResult
|
||||||
{
|
{
|
||||||
public List<MqttClientSubscribeResultItem> Items { get; } = new List<MqttClientSubscribeResultItem>();
|
public List<MqttClientSubscribeResultItem> Items { get; } = new List<MqttClientSubscribeResultItem>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the user properties which were part of the SUBACK packet.
|
||||||
|
/// MQTTv5 only.
|
||||||
|
/// </summary>
|
||||||
|
public List<MqttUserProperty> UserProperties { get; } = new List<MqttUserProperty>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the reason string.
|
||||||
|
/// MQTTv5 only.
|
||||||
|
/// </summary>
|
||||||
|
public string ReasonString { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,11 @@
|
|||||||
{
|
{
|
||||||
public enum MqttClientSubscribeResultCode
|
public enum MqttClientSubscribeResultCode
|
||||||
{
|
{
|
||||||
GrantedQoS0 = 0,
|
GrantedQoS0 = 0x00,
|
||||||
GrantedQoS1 = 1,
|
GrantedQoS1 = 0x01,
|
||||||
GrantedQoS2 = 2,
|
GrantedQoS2 = 0x02,
|
||||||
UnspecifiedError = 128,
|
UnspecifiedError = 0x80,
|
||||||
|
|
||||||
ImplementationSpecificError = 131,
|
ImplementationSpecificError = 131,
|
||||||
NotAuthorized = 135,
|
NotAuthorized = 135,
|
||||||
TopicFilterInvalid = 143,
|
TopicFilterInvalid = 143,
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using MQTTnet.Exceptions;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
|
||||||
|
namespace MQTTnet.Client.Subscribing
|
||||||
|
{
|
||||||
|
public sealed class MqttClientSubscribeResultFactory
|
||||||
|
{
|
||||||
|
public MqttClientSubscribeResult Create(MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket)
|
||||||
|
{
|
||||||
|
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
||||||
|
if (subAckPacket == null) throw new ArgumentNullException(nameof(subAckPacket));
|
||||||
|
|
||||||
|
// MQTTv3.1.1 handling.
|
||||||
|
if (subAckPacket.ReturnCodes.Any() && subAckPacket.ReturnCodes.Count != subscribePacket.TopicFilters.Count)
|
||||||
|
{
|
||||||
|
throw new MqttProtocolViolationException(
|
||||||
|
"The return codes are not matching the topic filters [MQTT-3.9.3-1].");
|
||||||
|
}
|
||||||
|
|
||||||
|
// MQTTv5.0.0 handling.
|
||||||
|
if (subAckPacket.ReasonCodes.Any() && subAckPacket.ReasonCodes.Count != subscribePacket.TopicFilters.Count)
|
||||||
|
{
|
||||||
|
throw new MqttProtocolViolationException(
|
||||||
|
"The reason codes are not matching the topic filters [MQTT-3.9.3-1].");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new MqttClientSubscribeResult
|
||||||
|
{
|
||||||
|
ReasonString = subAckPacket.Properties.ReasonString
|
||||||
|
};
|
||||||
|
|
||||||
|
result.UserProperties.AddRange(subAckPacket.Properties.UserProperties);
|
||||||
|
|
||||||
|
for (var i = 0; i < subscribePacket.TopicFilters.Count; i++)
|
||||||
|
{
|
||||||
|
result.Items.Add(CreateSubscribeResultItem(i, subscribePacket, subAckPacket));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MqttClientSubscribeResultItem CreateSubscribeResultItem(int index, MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket)
|
||||||
|
{
|
||||||
|
MqttClientSubscribeResultCode resultCode;
|
||||||
|
|
||||||
|
if (subAckPacket.ReturnCodes.Any())
|
||||||
|
{
|
||||||
|
// MQTTv3.1.1 handling.
|
||||||
|
resultCode = (MqttClientSubscribeResultCode) subAckPacket.ReturnCodes[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// MQTTv5.0.0 handling.
|
||||||
|
resultCode = (MqttClientSubscribeResultCode) subAckPacket.ReasonCodes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MqttClientSubscribeResultItem
|
||||||
|
{
|
||||||
|
TopicFilter = subscribePacket.TopicFilters[index],
|
||||||
|
ResultCode = resultCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,17 @@
|
|||||||
using System;
|
namespace MQTTnet.Client.Subscribing
|
||||||
|
|
||||||
namespace MQTTnet.Client.Subscribing
|
|
||||||
{
|
{
|
||||||
public class MqttClientSubscribeResultItem
|
public sealed class MqttClientSubscribeResultItem
|
||||||
{
|
{
|
||||||
public MqttClientSubscribeResultItem(MqttTopicFilter topicFilter, MqttClientSubscribeResultCode resultCode)
|
|
||||||
{
|
|
||||||
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
|
|
||||||
ResultCode = resultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the topic filter.
|
/// Gets or sets the topic filter.
|
||||||
/// The topic filter can contain topics and wildcards.
|
/// The topic filter can contain topics and wildcards.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MqttTopicFilter TopicFilter { get; }
|
public MqttTopicFilter TopicFilter { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the result code.
|
/// Gets or sets the result code.
|
||||||
/// Hint: MQTT 5 feature only.
|
/// Hint: MQTT 5 feature only.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MqttClientSubscribeResultCode ResultCode { get; }
|
public MqttClientSubscribeResultCode ResultCode { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using MQTTnet.Packets;
|
|||||||
|
|
||||||
namespace MQTTnet.Client.Unsubscribing
|
namespace MQTTnet.Client.Unsubscribing
|
||||||
{
|
{
|
||||||
public class MqttClientUnsubscribeOptions
|
public sealed class MqttClientUnsubscribeOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a list of topic filters the client wants to unsubscribe from.
|
/// Gets or sets a list of topic filters the client wants to unsubscribe from.
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
|
||||||
namespace MQTTnet.Client.Unsubscribing
|
namespace MQTTnet.Client.Unsubscribing
|
||||||
{
|
{
|
||||||
public class MqttClientUnsubscribeResult
|
public sealed class MqttClientUnsubscribeResult
|
||||||
{
|
{
|
||||||
public List<MqttClientUnsubscribeResultItem> Items { get; } =new List<MqttClientUnsubscribeResultItem>();
|
public List<MqttClientUnsubscribeResultItem> Items { get; } =new List<MqttClientUnsubscribeResultItem>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the user properties which were part of the UNSUBACK packet.
|
||||||
|
/// MQTTv5 only.
|
||||||
|
/// </summary>
|
||||||
|
public List<MqttUserProperty> UserProperties { get; } = new List<MqttUserProperty>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the reason string.
|
||||||
|
/// MQTTv5 only.
|
||||||
|
/// </summary>
|
||||||
|
public string ReasonString { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using MQTTnet.Exceptions;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
|
||||||
|
namespace MQTTnet.Client.Unsubscribing
|
||||||
|
{
|
||||||
|
public sealed class MqttClientUnsubscribeResultFactory
|
||||||
|
{
|
||||||
|
public MqttClientUnsubscribeResult Create(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
|
||||||
|
{
|
||||||
|
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
||||||
|
if (unsubAckPacket == null) throw new ArgumentNullException(nameof(unsubAckPacket));
|
||||||
|
|
||||||
|
// MQTTv3.1.1 has no reason code at all!
|
||||||
|
if (unsubAckPacket.ReasonCodes.Count != 0 && unsubAckPacket.ReasonCodes.Count != unsubscribePacket.TopicFilters.Count)
|
||||||
|
{
|
||||||
|
throw new MqttProtocolViolationException(
|
||||||
|
"The return codes are not matching the topic filters [MQTT-3.9.3-1].");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new MqttClientUnsubscribeResult
|
||||||
|
{
|
||||||
|
ReasonString = unsubAckPacket.Properties.ReasonString
|
||||||
|
};
|
||||||
|
|
||||||
|
result.UserProperties.AddRange(unsubAckPacket.Properties.UserProperties);
|
||||||
|
|
||||||
|
for (var i = 0; i < unsubscribePacket.TopicFilters.Count; i++)
|
||||||
|
{
|
||||||
|
result.Items.Add(CreateUnsubscribeResultItem(i, unsubscribePacket, unsubAckPacket));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MqttClientUnsubscribeResultItem CreateUnsubscribeResultItem(int index, MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
|
||||||
|
{
|
||||||
|
var resultCode = MqttClientUnsubscribeResultCode.Success;
|
||||||
|
|
||||||
|
if (unsubAckPacket.ReasonCodes.Any())
|
||||||
|
{
|
||||||
|
// MQTTv3.1.1 has no reason code and no return code!.
|
||||||
|
resultCode = (MqttClientUnsubscribeResultCode) unsubAckPacket.ReasonCodes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MqttClientUnsubscribeResultItem
|
||||||
|
{
|
||||||
|
TopicFilter = unsubscribePacket.TopicFilters[index],
|
||||||
|
ResultCode = resultCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,24 +2,21 @@
|
|||||||
|
|
||||||
namespace MQTTnet.Client.Unsubscribing
|
namespace MQTTnet.Client.Unsubscribing
|
||||||
{
|
{
|
||||||
public class MqttClientUnsubscribeResultItem
|
public sealed class MqttClientUnsubscribeResultItem
|
||||||
{
|
{
|
||||||
public MqttClientUnsubscribeResultItem(string topicFilter, MqttClientUnsubscribeResultCode reasonCode)
|
|
||||||
{
|
|
||||||
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
|
|
||||||
ReasonCode = reasonCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the topic filter.
|
/// Gets or sets the topic filter.
|
||||||
/// The topic filter can contain topics and wildcards.
|
/// The topic filter can contain topics and wildcards.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TopicFilter { get; }
|
public string TopicFilter { get; internal set; }
|
||||||
|
|
||||||
|
[Obsolete("Use ResultCode instead. This property will be removed soon.")]
|
||||||
|
public MqttClientUnsubscribeResultCode ReasonCode => ResultCode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the result code.
|
/// Gets or sets the result code.
|
||||||
/// Hint: MQTT 5 feature only.
|
/// Hint: MQTT 5 feature only.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MqttClientUnsubscribeResultCode ReasonCode { get; }
|
public MqttClientUnsubscribeResultCode ResultCode { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using MQTTnet.Client.Connecting;
|
|
||||||
using MQTTnet.Client.Publishing;
|
|
||||||
using MQTTnet.Client.Subscribing;
|
|
||||||
using MQTTnet.Client.Unsubscribing;
|
|
||||||
using MQTTnet.Packets;
|
|
||||||
using MQTTnet.Server.Internal;
|
|
||||||
|
|
||||||
namespace MQTTnet.Formatter
|
|
||||||
{
|
|
||||||
public interface IMqttDataConverter
|
|
||||||
{
|
|
||||||
MqttClientConnectResult CreateClientConnectResult(MqttConnAckPacket connAckPacket);
|
|
||||||
|
|
||||||
MqttClientPublishResult CreateClientPublishResult(MqttPubAckPacket pubAckPacket);
|
|
||||||
|
|
||||||
MqttClientPublishResult CreateClientPublishResult(MqttPubRecPacket pubRecPacket, MqttPubCompPacket pubCompPacket);
|
|
||||||
|
|
||||||
MqttClientSubscribeResult CreateClientSubscribeResult(MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket);
|
|
||||||
|
|
||||||
MqttClientUnsubscribeResult CreateClientUnsubscribeResult(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket);
|
|
||||||
|
|
||||||
MqttPubCompPacket CreatePubCompPacket(MqttPubRelPacket pubRelPacket, MqttApplicationMessageReceivedReasonCode reasonCode);
|
|
||||||
|
|
||||||
MqttPubRelPacket CreatePubRelPacket(MqttPubRecPacket pubRecPacket, MqttApplicationMessageReceivedReasonCode reasonCode);
|
|
||||||
|
|
||||||
MqttSubAckPacket CreateSubAckPacket(MqttSubscribePacket subscribePacket, SubscribeResult subscribeResult);
|
|
||||||
|
|
||||||
MqttUnsubAckPacket CreateUnsubAckPacket(MqttUnsubscribePacket unsubscribePacket, UnsubscribeResult unsubscribeResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,6 @@ namespace MQTTnet.Formatter
|
|||||||
{
|
{
|
||||||
public interface IMqttPacketFormatter
|
public interface IMqttPacketFormatter
|
||||||
{
|
{
|
||||||
IMqttDataConverter DataConverter { get; }
|
|
||||||
|
|
||||||
ArraySegment<byte> Encode(MqttBasePacket mqttPacket);
|
ArraySegment<byte> Encode(MqttBasePacket mqttPacket);
|
||||||
|
|
||||||
MqttBasePacket Decode(ReceivedMqttPacket receivedMqttPacket);
|
MqttBasePacket Decode(ReceivedMqttPacket receivedMqttPacket);
|
||||||
|
|||||||
@@ -29,17 +29,7 @@ namespace MQTTnet.Formatter
|
|||||||
}
|
}
|
||||||
|
|
||||||
public MqttProtocolVersion ProtocolVersion { get; private set; } = MqttProtocolVersion.Unknown;
|
public MqttProtocolVersion ProtocolVersion { get; private set; } = MqttProtocolVersion.Unknown;
|
||||||
|
|
||||||
public IMqttDataConverter DataConverter
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
ThrowIfFormatterNotSet();
|
|
||||||
|
|
||||||
return _formatter.DataConverter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMqttPacketWriter Writer { get; }
|
public IMqttPacketWriter Writer { get; }
|
||||||
|
|
||||||
public ArraySegment<byte> Encode(MqttBasePacket packet)
|
public ArraySegment<byte> Encode(MqttBasePacket packet)
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Protocol;
|
||||||
|
|
||||||
|
namespace MQTTnet.Formatter
|
||||||
|
{
|
||||||
|
public sealed class MqttPubCompPacketFactory
|
||||||
|
{
|
||||||
|
public MqttPubCompPacket Create(MqttPubRelPacket pubRelPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
|
||||||
|
{
|
||||||
|
if (pubRelPacket == null) throw new ArgumentNullException(nameof(pubRelPacket));
|
||||||
|
|
||||||
|
return new MqttPubCompPacket
|
||||||
|
{
|
||||||
|
PacketIdentifier = pubRelPacket.PacketIdentifier,
|
||||||
|
ReasonCode = (MqttPubCompReasonCode) (int) reasonCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Protocol;
|
||||||
|
|
||||||
|
namespace MQTTnet.Formatter
|
||||||
|
{
|
||||||
|
public sealed class MqttPubRelPacketFactory
|
||||||
|
{
|
||||||
|
public MqttPubRelPacket Create(MqttPubRecPacket pubRecPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
|
||||||
|
{
|
||||||
|
if (pubRecPacket == null) throw new ArgumentNullException(nameof(pubRecPacket));
|
||||||
|
|
||||||
|
return new MqttPubRelPacket
|
||||||
|
{
|
||||||
|
PacketIdentifier = pubRecPacket.PacketIdentifier,
|
||||||
|
ReasonCode = (MqttPubRelReasonCode) (int) reasonCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Server.Internal;
|
||||||
|
|
||||||
|
namespace MQTTnet.Formatter
|
||||||
|
{
|
||||||
|
public sealed class MqttSubAckPacketFactory
|
||||||
|
{
|
||||||
|
public MqttSubAckPacket Create(MqttSubscribePacket subscribePacket, SubscribeResult subscribeResult)
|
||||||
|
{
|
||||||
|
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
||||||
|
if (subscribeResult == null) throw new ArgumentNullException(nameof(subscribeResult));
|
||||||
|
|
||||||
|
var subAckPacket = new MqttSubAckPacket
|
||||||
|
{
|
||||||
|
PacketIdentifier = subscribePacket.PacketIdentifier
|
||||||
|
};
|
||||||
|
|
||||||
|
// MQTTv3.1.1
|
||||||
|
subAckPacket.ReturnCodes.AddRange(subscribeResult.ReturnCodes);
|
||||||
|
|
||||||
|
// MQTTv5.0.0
|
||||||
|
subAckPacket.ReasonCodes.AddRange(subscribeResult.ReasonCodes);
|
||||||
|
|
||||||
|
return subAckPacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using MQTTnet.Packets;
|
||||||
|
using MQTTnet.Server.Internal;
|
||||||
|
|
||||||
|
namespace MQTTnet.Formatter
|
||||||
|
{
|
||||||
|
public sealed class MqttUnsubAckPacketFactory
|
||||||
|
{
|
||||||
|
public MqttUnsubAckPacket Create(MqttUnsubscribePacket unsubscribePacket, UnsubscribeResult unsubscribeResult)
|
||||||
|
{
|
||||||
|
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
||||||
|
if (unsubscribeResult == null) throw new ArgumentNullException(nameof(unsubscribeResult));
|
||||||
|
|
||||||
|
var unsubAckPacket = new MqttUnsubAckPacket
|
||||||
|
{
|
||||||
|
PacketIdentifier = unsubscribePacket.PacketIdentifier
|
||||||
|
};
|
||||||
|
|
||||||
|
// MQTTv5.0.0 only.
|
||||||
|
unsubAckPacket.ReasonCodes.AddRange(unsubscribeResult.ReasonCodes);
|
||||||
|
|
||||||
|
return unsubAckPacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
using MQTTnet.Client.Connecting;
|
|
||||||
using MQTTnet.Client.Publishing;
|
|
||||||
using MQTTnet.Client.Subscribing;
|
|
||||||
using MQTTnet.Client.Unsubscribing;
|
|
||||||
using MQTTnet.Exceptions;
|
|
||||||
using MQTTnet.Packets;
|
|
||||||
using MQTTnet.Protocol;
|
|
||||||
using MQTTnet.Server;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using MQTTnet.Server.Internal;
|
|
||||||
|
|
||||||
namespace MQTTnet.Formatter.V3
|
|
||||||
{
|
|
||||||
public class MqttV310DataConverter : IMqttDataConverter
|
|
||||||
{
|
|
||||||
public MqttPubCompPacket CreatePubCompPacket(MqttPubRelPacket pubRelPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
|
|
||||||
{
|
|
||||||
if (pubRelPacket == null) throw new ArgumentNullException(nameof(pubRelPacket));
|
|
||||||
|
|
||||||
return new MqttPubCompPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubRelPacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttPubRelPacket CreatePubRelPacket(MqttPubRecPacket pubRecPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
|
|
||||||
{
|
|
||||||
if (pubRecPacket == null) throw new ArgumentNullException(nameof(pubRecPacket));
|
|
||||||
|
|
||||||
return new MqttPubRelPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubRecPacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientConnectResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
|
|
||||||
{
|
|
||||||
if (connAckPacket == null) throw new ArgumentNullException(nameof(connAckPacket));
|
|
||||||
|
|
||||||
MqttClientConnectResultCode resultCode;
|
|
||||||
switch (connAckPacket.ReturnCode)
|
|
||||||
{
|
|
||||||
case MqttConnectReturnCode.ConnectionAccepted:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.Success;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.UnsupportedProtocolVersion;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MqttConnectReturnCode.ConnectionRefusedNotAuthorized:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.NotAuthorized;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.BadUserNameOrPassword;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.ClientIdentifierNotValid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MqttConnectReturnCode.ConnectionRefusedServerUnavailable:
|
|
||||||
{
|
|
||||||
resultCode = MqttClientConnectResultCode.ServerUnavailable;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new MqttProtocolViolationException("Received unexpected return code.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MqttClientConnectResult
|
|
||||||
{
|
|
||||||
RetainAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
|
|
||||||
WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
|
|
||||||
IsSessionPresent = connAckPacket.IsSessionPresent,
|
|
||||||
ResultCode = resultCode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientSubscribeResult CreateClientSubscribeResult(MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket)
|
|
||||||
{
|
|
||||||
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
|
||||||
if (subAckPacket == null) throw new ArgumentNullException(nameof(subAckPacket));
|
|
||||||
|
|
||||||
if (subAckPacket.ReturnCodes.Count != subscribePacket.TopicFilters.Count)
|
|
||||||
{
|
|
||||||
throw new MqttProtocolViolationException("The return codes are not matching the topic filters [MQTT-3.9.3-1].");
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new MqttClientSubscribeResult();
|
|
||||||
|
|
||||||
result.Items.AddRange(subscribePacket.TopicFilters.Select((t, i) =>
|
|
||||||
new MqttClientSubscribeResultItem(t, (MqttClientSubscribeResultCode)subAckPacket.ReturnCodes[i])));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientUnsubscribeResult CreateClientUnsubscribeResult(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
|
|
||||||
{
|
|
||||||
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
|
||||||
if (unsubAckPacket == null) throw new ArgumentNullException(nameof(unsubAckPacket));
|
|
||||||
|
|
||||||
var result = new MqttClientUnsubscribeResult();
|
|
||||||
|
|
||||||
result.Items.AddRange(unsubscribePacket.TopicFilters.Select((t, i) =>
|
|
||||||
new MqttClientUnsubscribeResultItem(t, MqttClientUnsubscribeResultCode.Success)));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttSubAckPacket CreateSubAckPacket(MqttSubscribePacket subscribePacket, SubscribeResult subscribeResult)
|
|
||||||
{
|
|
||||||
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
|
||||||
if (subscribeResult == null) throw new ArgumentNullException(nameof(subscribeResult));
|
|
||||||
|
|
||||||
var subAckPacket = new MqttSubAckPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = subscribePacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
|
|
||||||
subAckPacket.ReturnCodes.AddRange(subscribeResult.ReturnCodes);
|
|
||||||
|
|
||||||
return subAckPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttUnsubAckPacket CreateUnsubAckPacket(MqttUnsubscribePacket unsubscribePacket, UnsubscribeResult _)
|
|
||||||
{
|
|
||||||
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
|
||||||
|
|
||||||
// The UnsubscribeResult is not supported in protocol version 3.1.1!
|
|
||||||
return new MqttUnsubAckPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = unsubscribePacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientPublishResult CreateClientPublishResult(MqttPubAckPacket pubAckPacket)
|
|
||||||
{
|
|
||||||
return new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubAckPacket?.PacketIdentifier,
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientPublishResult CreateClientPublishResult(MqttPubRecPacket pubRecPacket, MqttPubCompPacket pubCompPacket)
|
|
||||||
{
|
|
||||||
if (pubRecPacket == null || pubCompPacket == null)
|
|
||||||
{
|
|
||||||
return new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using MQTTnet.Adapter;
|
using MQTTnet.Adapter;
|
||||||
using MQTTnet.Exceptions;
|
using MQTTnet.Exceptions;
|
||||||
@@ -12,9 +11,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
public class MqttV310PacketFormatter : IMqttPacketFormatter
|
public class MqttV310PacketFormatter : IMqttPacketFormatter
|
||||||
{
|
{
|
||||||
const int FixedHeaderSize = 1;
|
const int FixedHeaderSize = 1;
|
||||||
|
|
||||||
static readonly MqttPingReqPacket PingReqPacket = new MqttPingReqPacket();
|
|
||||||
static readonly MqttPingRespPacket PingRespPacket = new MqttPingRespPacket();
|
|
||||||
static readonly MqttDisconnectPacket DisconnectPacket = new MqttDisconnectPacket();
|
static readonly MqttDisconnectPacket DisconnectPacket = new MqttDisconnectPacket();
|
||||||
|
|
||||||
readonly IMqttPacketWriter _packetWriter;
|
readonly IMqttPacketWriter _packetWriter;
|
||||||
@@ -24,8 +21,6 @@ namespace MQTTnet.Formatter.V3
|
|||||||
_packetWriter = packetWriter;
|
_packetWriter = packetWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMqttDataConverter DataConverter { get; } = new MqttV310DataConverter();
|
|
||||||
|
|
||||||
public ArraySegment<byte> Encode(MqttBasePacket packet)
|
public ArraySegment<byte> Encode(MqttBasePacket packet)
|
||||||
{
|
{
|
||||||
if (packet == null) throw new ArgumentNullException(nameof(packet));
|
if (packet == null) throw new ArgumentNullException(nameof(packet));
|
||||||
@@ -72,8 +67,8 @@ namespace MQTTnet.Formatter.V3
|
|||||||
case MqttControlPacketType.PubRec: return DecodePubRecPacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.PubRec: return DecodePubRecPacket(receivedMqttPacket.BodyReader);
|
||||||
case MqttControlPacketType.PubRel: return DecodePubRelPacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.PubRel: return DecodePubRelPacket(receivedMqttPacket.BodyReader);
|
||||||
case MqttControlPacketType.PubComp: return DecodePubCompPacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.PubComp: return DecodePubCompPacket(receivedMqttPacket.BodyReader);
|
||||||
case MqttControlPacketType.PingReq: return PingReqPacket;
|
case MqttControlPacketType.PingReq: return MqttPingReqPacket.Instance;
|
||||||
case MqttControlPacketType.PingResp: return PingRespPacket;
|
case MqttControlPacketType.PingResp: return MqttPingRespPacket.Instance;
|
||||||
case MqttControlPacketType.Subscribe: return DecodeSubscribePacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.Subscribe: return DecodeSubscribePacket(receivedMqttPacket.BodyReader);
|
||||||
case MqttControlPacketType.SubAck: return DecodeSubAckPacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.SubAck: return DecodeSubAckPacket(receivedMqttPacket.BodyReader);
|
||||||
case MqttControlPacketType.Unsubscibe: return DecodeUnsubscribePacket(receivedMqttPacket.BodyReader);
|
case MqttControlPacketType.Unsubscibe: return DecodeUnsubscribePacket(receivedMqttPacket.BodyReader);
|
||||||
|
|||||||
@@ -1,202 +0,0 @@
|
|||||||
using MQTTnet.Client.Connecting;
|
|
||||||
using MQTTnet.Client.Publishing;
|
|
||||||
using MQTTnet.Client.Subscribing;
|
|
||||||
using MQTTnet.Client.Unsubscribing;
|
|
||||||
using MQTTnet.Exceptions;
|
|
||||||
using MQTTnet.Packets;
|
|
||||||
using MQTTnet.Protocol;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using MQTTnet.Server.Internal;
|
|
||||||
|
|
||||||
namespace MQTTnet.Formatter.V5
|
|
||||||
{
|
|
||||||
public sealed class MqttV500DataConverter : IMqttDataConverter
|
|
||||||
{
|
|
||||||
public MqttPubCompPacket CreatePubCompPacket(MqttPubRelPacket pubRelPacket,
|
|
||||||
MqttApplicationMessageReceivedReasonCode reasonCode)
|
|
||||||
{
|
|
||||||
if (pubRelPacket == null) throw new ArgumentNullException(nameof(pubRelPacket));
|
|
||||||
|
|
||||||
return new MqttPubCompPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubRelPacket.PacketIdentifier,
|
|
||||||
ReasonCode = (MqttPubCompReasonCode) (int) reasonCode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttPubRelPacket CreatePubRelPacket(MqttPubRecPacket pubRecPacket,
|
|
||||||
MqttApplicationMessageReceivedReasonCode reasonCode)
|
|
||||||
{
|
|
||||||
if (pubRecPacket == null) throw new ArgumentNullException(nameof(pubRecPacket));
|
|
||||||
|
|
||||||
return new MqttPubRelPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubRecPacket.PacketIdentifier,
|
|
||||||
ReasonCode = (MqttPubRelReasonCode) (int) reasonCode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientConnectResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
|
|
||||||
{
|
|
||||||
if (connAckPacket == null) throw new ArgumentNullException(nameof(connAckPacket));
|
|
||||||
|
|
||||||
return new MqttClientConnectResult
|
|
||||||
{
|
|
||||||
IsSessionPresent = connAckPacket.IsSessionPresent,
|
|
||||||
ResultCode = (MqttClientConnectResultCode) (int) connAckPacket.ReasonCode,
|
|
||||||
WildcardSubscriptionAvailable = connAckPacket.Properties?.WildcardSubscriptionAvailable ?? true,
|
|
||||||
RetainAvailable = connAckPacket.Properties?.RetainAvailable ?? true,
|
|
||||||
AssignedClientIdentifier = connAckPacket.Properties?.AssignedClientIdentifier,
|
|
||||||
AuthenticationMethod = connAckPacket.Properties?.AuthenticationMethod,
|
|
||||||
AuthenticationData = connAckPacket.Properties?.AuthenticationData,
|
|
||||||
MaximumPacketSize = connAckPacket.Properties?.MaximumPacketSize,
|
|
||||||
ReasonString = connAckPacket.Properties?.ReasonString,
|
|
||||||
ReceiveMaximum = connAckPacket.Properties?.ReceiveMaximum,
|
|
||||||
MaximumQoS = connAckPacket.Properties?.MaximumQoS ?? MqttQualityOfServiceLevel.ExactlyOnce,
|
|
||||||
ResponseInformation = connAckPacket.Properties?.ResponseInformation,
|
|
||||||
TopicAliasMaximum = connAckPacket.Properties?.TopicAliasMaximum ?? 0,
|
|
||||||
ServerReference = connAckPacket.Properties?.ServerReference,
|
|
||||||
ServerKeepAlive = connAckPacket.Properties?.ServerKeepAlive,
|
|
||||||
SessionExpiryInterval = connAckPacket.Properties?.SessionExpiryInterval,
|
|
||||||
SubscriptionIdentifiersAvailable = connAckPacket.Properties?.SubscriptionIdentifiersAvailable ?? true,
|
|
||||||
SharedSubscriptionAvailable = connAckPacket.Properties?.SharedSubscriptionAvailable ?? true,
|
|
||||||
UserProperties = connAckPacket.Properties?.UserProperties ?? new List<MqttUserProperty>()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientSubscribeResult CreateClientSubscribeResult(MqttSubscribePacket subscribePacket,
|
|
||||||
MqttSubAckPacket subAckPacket)
|
|
||||||
{
|
|
||||||
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
|
||||||
if (subAckPacket == null) throw new ArgumentNullException(nameof(subAckPacket));
|
|
||||||
|
|
||||||
if (subAckPacket.ReasonCodes.Count != subscribePacket.TopicFilters.Count)
|
|
||||||
{
|
|
||||||
throw new MqttProtocolViolationException(
|
|
||||||
"The reason codes are not matching the topic filters [MQTT-3.9.3-1].");
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new MqttClientSubscribeResult();
|
|
||||||
|
|
||||||
result.Items.AddRange(subscribePacket.TopicFilters.Select((t, i) =>
|
|
||||||
new MqttClientSubscribeResultItem(t, (MqttClientSubscribeResultCode) subAckPacket.ReasonCodes[i])));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientUnsubscribeResult CreateClientUnsubscribeResult(MqttUnsubscribePacket unsubscribePacket,
|
|
||||||
MqttUnsubAckPacket unsubAckPacket)
|
|
||||||
{
|
|
||||||
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
|
||||||
if (unsubAckPacket == null) throw new ArgumentNullException(nameof(unsubAckPacket));
|
|
||||||
|
|
||||||
if (unsubAckPacket.ReasonCodes.Count != unsubscribePacket.TopicFilters.Count)
|
|
||||||
{
|
|
||||||
throw new MqttProtocolViolationException(
|
|
||||||
"The return codes are not matching the topic filters [MQTT-3.9.3-1].");
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new MqttClientUnsubscribeResult();
|
|
||||||
|
|
||||||
result.Items.AddRange(unsubscribePacket.TopicFilters.Select((t, i) =>
|
|
||||||
new MqttClientUnsubscribeResultItem(t,
|
|
||||||
(MqttClientUnsubscribeResultCode) unsubAckPacket.ReasonCodes[i])));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttSubAckPacket CreateSubAckPacket(MqttSubscribePacket subscribePacket, SubscribeResult subscribeResult)
|
|
||||||
{
|
|
||||||
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
|
||||||
if (subscribeResult == null) throw new ArgumentNullException(nameof(subscribeResult));
|
|
||||||
|
|
||||||
var subAckPacket = new MqttSubAckPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = subscribePacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
|
|
||||||
subAckPacket.ReasonCodes.AddRange(subscribeResult.ReasonCodes);
|
|
||||||
|
|
||||||
return subAckPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttUnsubAckPacket CreateUnsubAckPacket(MqttUnsubscribePacket unsubscribePacket,
|
|
||||||
UnsubscribeResult unsubscribeResult)
|
|
||||||
{
|
|
||||||
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
|
||||||
if (unsubscribeResult == null) throw new ArgumentNullException(nameof(unsubscribeResult));
|
|
||||||
|
|
||||||
var unsubAckPacket = new MqttUnsubAckPacket
|
|
||||||
{
|
|
||||||
PacketIdentifier = unsubscribePacket.PacketIdentifier
|
|
||||||
};
|
|
||||||
|
|
||||||
unsubAckPacket.ReasonCodes.AddRange(unsubscribeResult.ReasonCodes);
|
|
||||||
|
|
||||||
return unsubAckPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientPublishResult CreateClientPublishResult(MqttPubAckPacket pubAckPacket)
|
|
||||||
{
|
|
||||||
var result = new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success,
|
|
||||||
ReasonString = pubAckPacket?.Properties?.ReasonString,
|
|
||||||
UserProperties = pubAckPacket?.Properties?.UserProperties
|
|
||||||
};
|
|
||||||
|
|
||||||
if (pubAckPacket != null)
|
|
||||||
{
|
|
||||||
// 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) (int) pubAckPacket.ReasonCode;
|
|
||||||
|
|
||||||
result.PacketIdentifier = pubAckPacket.PacketIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MqttClientPublishResult CreateClientPublishResult(MqttPubRecPacket pubRecPacket,
|
|
||||||
MqttPubCompPacket pubCompPacket)
|
|
||||||
{
|
|
||||||
if (pubRecPacket == null || pubCompPacket == null)
|
|
||||||
{
|
|
||||||
return new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// The PUBCOMP is the last packet in QoS 2. So we use the results from that instead of PUBREC.
|
|
||||||
if (pubCompPacket.ReasonCode == MqttPubCompReasonCode.PacketIdentifierNotFound)
|
|
||||||
{
|
|
||||||
return new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError,
|
|
||||||
ReasonString = pubCompPacket.Properties?.ReasonString,
|
|
||||||
UserProperties = pubCompPacket.Properties?.UserProperties
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new MqttClientPublishResult
|
|
||||||
{
|
|
||||||
PacketIdentifier = pubCompPacket.PacketIdentifier,
|
|
||||||
ReasonCode = MqttClientPublishReasonCode.Success,
|
|
||||||
ReasonString = pubCompPacket.Properties?.ReasonString,
|
|
||||||
UserProperties = pubCompPacket.Properties?.UserProperties
|
|
||||||
};
|
|
||||||
|
|
||||||
if (pubRecPacket.ReasonCode != MqttPubRecReasonCode.Success)
|
|
||||||
{
|
|
||||||
// Both enums share the same values.
|
|
||||||
result.ReasonCode = (MqttClientPublishReasonCode) pubRecPacket.ReasonCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,8 +13,6 @@ namespace MQTTnet.Formatter.V5
|
|||||||
{
|
{
|
||||||
_encoder = new MqttV500PacketEncoder(writer);
|
_encoder = new MqttV500PacketEncoder(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMqttDataConverter DataConverter { get; } = new MqttV500DataConverter();
|
|
||||||
|
|
||||||
public ArraySegment<byte> Encode(MqttBasePacket mqttPacket)
|
public ArraySegment<byte> Encode(MqttBasePacket mqttPacket)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,10 +2,13 @@
|
|||||||
{
|
{
|
||||||
public enum MqttSubscribeReasonCode
|
public enum MqttSubscribeReasonCode
|
||||||
{
|
{
|
||||||
GrantedQoS0 = 0,
|
// Compatible with MQTTv3.1.1.
|
||||||
GrantedQoS1 = 1,
|
GrantedQoS0 = 0x00,
|
||||||
GrantedQoS2 = 2,
|
GrantedQoS1 = 0x01,
|
||||||
UnspecifiedError = 128,
|
GrantedQoS2 = 0x02,
|
||||||
|
UnspecifiedError = 0x80,
|
||||||
|
|
||||||
|
// New in MQTTv5.
|
||||||
ImplementationSpecificError = 131,
|
ImplementationSpecificError = 131,
|
||||||
NotAuthorized = 135,
|
NotAuthorized = 135,
|
||||||
TopicFilterInvalid = 143,
|
TopicFilterInvalid = 143,
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MQTTnet.Adapter;
|
using MQTTnet.Adapter;
|
||||||
using MQTTnet.Client;
|
|
||||||
using MQTTnet.Client.Disconnecting;
|
using MQTTnet.Client.Disconnecting;
|
||||||
using MQTTnet.Diagnostics.Logger;
|
using MQTTnet.Diagnostics.Logger;
|
||||||
using MQTTnet.Exceptions;
|
using MQTTnet.Exceptions;
|
||||||
using MQTTnet.Formatter;
|
using MQTTnet.Formatter;
|
||||||
using MQTTnet.Formatter.V5;
|
|
||||||
using MQTTnet.Implementations;
|
using MQTTnet.Implementations;
|
||||||
using MQTTnet.Internal;
|
using MQTTnet.Internal;
|
||||||
using MQTTnet.PacketDispatcher;
|
using MQTTnet.PacketDispatcher;
|
||||||
@@ -20,7 +18,6 @@ namespace MQTTnet.Server.Internal
|
|||||||
public sealed class MqttClientConnection : IDisposable
|
public sealed class MqttClientConnection : IDisposable
|
||||||
{
|
{
|
||||||
readonly Dictionary<ushort, string> _topicAlias = new Dictionary<ushort, string>();
|
readonly Dictionary<ushort, string> _topicAlias = new Dictionary<ushort, string>();
|
||||||
readonly MqttPacketIdentifierProvider _packetIdentifierProvider = new MqttPacketIdentifierProvider();
|
|
||||||
readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
|
readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
|
||||||
|
|
||||||
readonly MqttClientSessionsManager _sessionsManager;
|
readonly MqttClientSessionsManager _sessionsManager;
|
||||||
@@ -162,7 +159,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
|
|
||||||
if (packet is MqttPublishPacket publishPacket)
|
if (packet is MqttPublishPacket publishPacket)
|
||||||
{
|
{
|
||||||
await HandleIncomingPublishPacket(publishPacket, cancellationToken).ConfigureAwait(false);
|
HandleIncomingPublishPacket(publishPacket);
|
||||||
}
|
}
|
||||||
else if (packet is MqttPubAckPacket pubAckPacket)
|
else if (packet is MqttPubAckPacket pubAckPacket)
|
||||||
{
|
{
|
||||||
@@ -176,7 +173,9 @@ namespace MQTTnet.Server.Internal
|
|||||||
{
|
{
|
||||||
// TODO: Do anything!
|
// TODO: Do anything!
|
||||||
// TODO: Send pub rel!
|
// TODO: Send pub rel!
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(ChannelAdapter.PacketFormatterAdapter.DataConverter.CreatePubRelPacket(pubRecPacket, MqttApplicationMessageReceivedReasonCode.Success)));
|
var pubRelPacketFactory = new MqttPubRelPacketFactory();
|
||||||
|
var pubRelPacket = pubRelPacketFactory.Create(pubRecPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
|
Session.EnqueuePacket(new MqttPacketBusItem(pubRelPacket));
|
||||||
}
|
}
|
||||||
else if (packet is MqttPubRelPacket pubRelPacket)
|
else if (packet is MqttPubRelPacket pubRelPacket)
|
||||||
{
|
{
|
||||||
@@ -390,16 +389,21 @@ namespace MQTTnet.Server.Internal
|
|||||||
|
|
||||||
Task HandleIncomingPubRelPacket(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
Task HandleIncomingPubRelPacket(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var pubCompPacket = ChannelAdapter.PacketFormatterAdapter.DataConverter.CreatePubCompPacket(pubRelPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
var pubCompPacketFactory = new MqttPubCompPacketFactory();
|
||||||
return SendPacketAsync(pubCompPacket, cancellationToken);
|
var pubCompPacket =pubCompPacketFactory.Create(pubRelPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
|
Session.EnqueuePacket(new MqttPacketBusItem(pubCompPacket));
|
||||||
|
|
||||||
|
//return SendPacketAsync(pubCompPacket, cancellationToken);
|
||||||
|
return PlatformAbstractionLayer.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task HandleIncomingSubscribePacket(MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
|
async Task HandleIncomingSubscribePacket(MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var subscribeResult = await Session.SubscriptionsManager.Subscribe(subscribePacket).ConfigureAwait(false);
|
var subscribeResult = await Session.SubscriptionsManager.Subscribe(subscribePacket, cancellationToken).ConfigureAwait(false);
|
||||||
var subAckPacket = ChannelAdapter.PacketFormatterAdapter.DataConverter.CreateSubAckPacket(subscribePacket, subscribeResult);
|
|
||||||
|
var subAckPacketFactory = new MqttSubAckPacketFactory();
|
||||||
|
var subAckPacket = subAckPacketFactory.Create(subscribePacket, subscribeResult);
|
||||||
|
|
||||||
//await SendPacketAsync(subAckPacket, cancellationToken).ConfigureAwait(false);
|
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(subAckPacket));
|
Session.EnqueuePacket(new MqttPacketBusItem(subAckPacket));
|
||||||
|
|
||||||
if (subscribeResult.CloseConnection)
|
if (subscribeResult.CloseConnection)
|
||||||
@@ -411,26 +415,27 @@ namespace MQTTnet.Server.Internal
|
|||||||
var publishPacketFactory = new MqttPublishPacketFactory();
|
var publishPacketFactory = new MqttPublishPacketFactory();
|
||||||
foreach (var retainedApplicationMessage in subscribeResult.RetainedApplicationMessages)
|
foreach (var retainedApplicationMessage in subscribeResult.RetainedApplicationMessages)
|
||||||
{
|
{
|
||||||
//var publishPacket = ChannelAdapter.PacketFormatterAdapter.DataConverter.CreatePublishPacket(retainedApplicationMessage.ApplicationMessage);
|
var publishPacket = publishPacketFactory.Create(retainedApplicationMessage.ApplicationMessage);
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(publishPacketFactory.Create(retainedApplicationMessage.ApplicationMessage)));
|
Session.EnqueuePacket(new MqttPacketBusItem(publishPacket));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task HandleIncomingUnsubscribePacket(MqttUnsubscribePacket unsubscribePacket, CancellationToken cancellationToken)
|
async Task HandleIncomingUnsubscribePacket(MqttUnsubscribePacket unsubscribePacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var unsubscribeResult = await Session.SubscriptionsManager.Unsubscribe(unsubscribePacket).ConfigureAwait(false);
|
var unsubscribeResult = await Session.SubscriptionsManager.Unsubscribe(unsubscribePacket, cancellationToken).ConfigureAwait(false);
|
||||||
var unsubAckPacket = ChannelAdapter.PacketFormatterAdapter.DataConverter.CreateUnsubAckPacket(unsubscribePacket, unsubscribeResult);
|
|
||||||
|
var unsubAckPacketFactory = new MqttUnsubAckPacketFactory();
|
||||||
|
var unsubAckPacket = unsubAckPacketFactory.Create(unsubscribePacket, unsubscribeResult);
|
||||||
|
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(unsubAckPacket));
|
Session.EnqueuePacket(new MqttPacketBusItem(unsubAckPacket));
|
||||||
//await SendPacketAsync(unsubAckPacket, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (unsubscribeResult.CloseConnection)
|
if (unsubscribeResult.CloseConnection)
|
||||||
{
|
{
|
||||||
StopInternal();
|
StopInternal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task HandleIncomingPublishPacket(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
void HandleIncomingPublishPacket(MqttPublishPacket publishPacket)
|
||||||
{
|
{
|
||||||
HandleTopicAlias(publishPacket);
|
HandleTopicAlias(publishPacket);
|
||||||
|
|
||||||
@@ -452,17 +457,13 @@ namespace MQTTnet.Server.Internal
|
|||||||
var pubAckPacketFactory = new MqttPubAckPacketFactory();
|
var pubAckPacketFactory = new MqttPubAckPacketFactory();
|
||||||
var pubAckPacket = pubAckPacketFactory.Create(publishPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
var pubAckPacket = pubAckPacketFactory.Create(publishPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(pubAckPacket));
|
Session.EnqueuePacket(new MqttPacketBusItem(pubAckPacket));
|
||||||
//return SendPacketAsync(pubAckPacket, cancellationToken);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MqttQualityOfServiceLevel.ExactlyOnce:
|
case MqttQualityOfServiceLevel.ExactlyOnce:
|
||||||
{
|
{
|
||||||
// TODO: Migrate to packet bus.
|
|
||||||
var pubRecPacketFactory = new MqttPubRecPacketFactory();
|
var pubRecPacketFactory = new MqttPubRecPacketFactory();
|
||||||
var pubRecPacket = pubRecPacketFactory.Create(publishPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
var pubRecPacket = pubRecPacketFactory.Create(publishPacket, MqttApplicationMessageReceivedReasonCode.Success);
|
||||||
Session.EnqueuePacket(new MqttPacketBusItem(pubRecPacket));
|
Session.EnqueuePacket(new MqttPacketBusItem(pubRecPacket));
|
||||||
|
|
||||||
//return SendPacketAsync(pubRecPacket, cancellationToken);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -470,8 +471,6 @@ namespace MQTTnet.Server.Internal
|
|||||||
throw new MqttCommunicationException("Received a not supported QoS level.");
|
throw new MqttCommunicationException("Received a not supported QoS level.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PlatformAbstractionLayer.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleTopicAlias(MqttPublishPacket publishPacket)
|
void HandleTopicAlias(MqttPublishPacket publishPacket)
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
|
|
||||||
var clientSession = GetClientSession(clientId);
|
var clientSession = GetClientSession(clientId);
|
||||||
|
|
||||||
var subscribeResult = await clientSession.SubscriptionsManager.Subscribe(fakeSubscribePacket).ConfigureAwait(false);
|
var subscribeResult = await clientSession.SubscriptionsManager.Subscribe(fakeSubscribePacket, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
foreach (var retainedApplicationMessage in subscribeResult.RetainedApplicationMessages)
|
foreach (var retainedApplicationMessage in subscribeResult.RetainedApplicationMessages)
|
||||||
{
|
{
|
||||||
@@ -257,7 +257,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
var fakeUnsubscribePacket = new MqttUnsubscribePacket();
|
var fakeUnsubscribePacket = new MqttUnsubscribePacket();
|
||||||
fakeUnsubscribePacket.TopicFilters.AddRange(topicFilters);
|
fakeUnsubscribePacket.TopicFilters.AddRange(topicFilters);
|
||||||
|
|
||||||
return GetClientSession(clientId).SubscriptionsManager.Unsubscribe(fakeUnsubscribePacket);
|
return GetClientSession(clientId).SubscriptionsManager.Unsubscribe(fakeUnsubscribePacket, CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteSessionAsync(string clientId)
|
public async Task DeleteSessionAsync(string clientId)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
|
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SubscribeResult> Subscribe(MqttSubscribePacket subscribePacket)
|
public async Task<SubscribeResult> Subscribe(MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
// lower one.
|
// lower one.
|
||||||
foreach (var originalTopicFilter in subscribePacket.TopicFilters.OrderByDescending(f => f.QualityOfServiceLevel))
|
foreach (var originalTopicFilter in subscribePacket.TopicFilters.OrderByDescending(f => f.QualityOfServiceLevel))
|
||||||
{
|
{
|
||||||
var interceptorContext = await InterceptSubscribe(originalTopicFilter).ConfigureAwait(false);
|
var interceptorContext = await InterceptSubscribe(originalTopicFilter, cancellationToken).ConfigureAwait(false);
|
||||||
var finalTopicFilter = interceptorContext.TopicFilter;
|
var finalTopicFilter = interceptorContext.TopicFilter;
|
||||||
var acceptSubscription = interceptorContext.ReasonCode <= MqttSubscribeReasonCode.GrantedQoS2;
|
var acceptSubscription = interceptorContext.ReasonCode <= MqttSubscribeReasonCode.GrantedQoS2;
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UnsubscribeResult> Unsubscribe(MqttUnsubscribePacket unsubscribePacket)
|
public async Task<UnsubscribeResult> Unsubscribe(MqttUnsubscribePacket unsubscribePacket, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace MQTTnet.Server.Internal
|
|||||||
{
|
{
|
||||||
_subscriptions.TryGetValue(topicFilter, out var existingSubscription);
|
_subscriptions.TryGetValue(topicFilter, out var existingSubscription);
|
||||||
|
|
||||||
var interceptorContext = await InterceptUnsubscribe(topicFilter, existingSubscription).ConfigureAwait(false);
|
var interceptorContext = await InterceptUnsubscribe(topicFilter, existingSubscription, cancellationToken).ConfigureAwait(false);
|
||||||
var acceptUnsubscription = interceptorContext.ReasonCode == MqttUnsubscribeReasonCode.Success;
|
var acceptUnsubscription = interceptorContext.ReasonCode == MqttUnsubscribeReasonCode.Success;
|
||||||
|
|
||||||
result.ReasonCodes.Add(interceptorContext.ReasonCode);
|
result.ReasonCodes.Add(interceptorContext.ReasonCode);
|
||||||
@@ -292,14 +292,15 @@ namespace MQTTnet.Server.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttSubscriptionInterceptorContext> InterceptSubscribe(MqttTopicFilter topicFilter)
|
async Task<MqttSubscriptionInterceptorContext> InterceptSubscribe(MqttTopicFilter topicFilter, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var context = new MqttSubscriptionInterceptorContext
|
var context = new MqttSubscriptionInterceptorContext
|
||||||
{
|
{
|
||||||
ClientId = _clientSession.ClientId,
|
ClientId = _clientSession.ClientId,
|
||||||
TopicFilter = topicFilter,
|
TopicFilter = topicFilter,
|
||||||
SessionItems = _clientSession.Items,
|
SessionItems = _clientSession.Items,
|
||||||
Session = new MqttSessionStatus(_clientSession)
|
Session = new MqttSessionStatus(_clientSession),
|
||||||
|
CancellationToken = cancellationToken
|
||||||
};
|
};
|
||||||
|
|
||||||
if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
|
if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
|
||||||
@@ -338,13 +339,14 @@ namespace MQTTnet.Server.Internal
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<MqttUnsubscriptionInterceptorContext> InterceptUnsubscribe(string topicFilter, Subscription subscription)
|
async Task<MqttUnsubscriptionInterceptorContext> InterceptUnsubscribe(string topicFilter, Subscription subscription, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var context = new MqttUnsubscriptionInterceptorContext
|
var context = new MqttUnsubscriptionInterceptorContext
|
||||||
{
|
{
|
||||||
ClientId = _clientSession.ClientId,
|
ClientId = _clientSession.ClientId,
|
||||||
Topic = topicFilter,
|
Topic = topicFilter,
|
||||||
SessionItems = _clientSession.Items
|
SessionItems = _clientSession.Items,
|
||||||
|
CancellationToken = cancellationToken
|
||||||
};
|
};
|
||||||
|
|
||||||
if (subscription == null)
|
if (subscription == null)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
using MQTTnet.Server.Status;
|
using MQTTnet.Server.Status;
|
||||||
|
|
||||||
@@ -74,5 +75,10 @@ namespace MQTTnet.Server
|
|||||||
/// Gets the current client session.
|
/// Gets the current client session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IMqttSessionStatus Session { get; internal set; }
|
public IMqttSessionStatus Session { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cancellation token which can indicate that the client connection gets down.
|
||||||
|
/// </summary>
|
||||||
|
public CancellationToken CancellationToken { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using MQTTnet.Protocol;
|
using MQTTnet.Protocol;
|
||||||
|
|
||||||
namespace MQTTnet.Server
|
namespace MQTTnet.Server
|
||||||
@@ -51,5 +52,10 @@ namespace MQTTnet.Server
|
|||||||
/// Gets or sets whether the broker should close the client connection.
|
/// Gets or sets whether the broker should close the client connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CloseConnection { get; set; }
|
public bool CloseConnection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cancellation token which can indicate that the client connection gets down.
|
||||||
|
/// </summary>
|
||||||
|
public CancellationToken CancellationToken { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using MQTTnet.Packets;
|
using MQTTnet.Packets;
|
||||||
@@ -22,7 +23,7 @@ namespace MQTTnet.Tests.Server
|
|||||||
var sp = new MqttSubscribePacket();
|
var sp = new MqttSubscribePacket();
|
||||||
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||||
|
|
||||||
await sm.Subscribe(sp);
|
await sm.Subscribe(sp, CancellationToken.None);
|
||||||
|
|
||||||
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "");
|
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "");
|
||||||
Assert.IsTrue(result.IsSubscribed);
|
Assert.IsTrue(result.IsSubscribed);
|
||||||
@@ -39,7 +40,7 @@ namespace MQTTnet.Tests.Server
|
|||||||
var sp = new MqttSubscribePacket();
|
var sp = new MqttSubscribePacket();
|
||||||
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce });
|
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce });
|
||||||
|
|
||||||
await sm.Subscribe(sp);
|
await sm.Subscribe(sp, CancellationToken.None);
|
||||||
|
|
||||||
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
|
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
|
||||||
Assert.IsTrue(result.IsSubscribed);
|
Assert.IsTrue(result.IsSubscribed);
|
||||||
@@ -57,7 +58,7 @@ namespace MQTTnet.Tests.Server
|
|||||||
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "#", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce });
|
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "#", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce });
|
||||||
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
|
sp.TopicFilters.Add(new MqttTopicFilter { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
|
||||||
|
|
||||||
await sm.Subscribe(sp);
|
await sm.Subscribe(sp, CancellationToken.None);
|
||||||
|
|
||||||
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
|
var result = sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
|
||||||
Assert.IsTrue(result.IsSubscribed);
|
Assert.IsTrue(result.IsSubscribed);
|
||||||
@@ -74,7 +75,7 @@ namespace MQTTnet.Tests.Server
|
|||||||
var sp = new MqttSubscribePacket();
|
var sp = new MqttSubscribePacket();
|
||||||
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||||
|
|
||||||
await sm.Subscribe(sp);
|
await sm.Subscribe(sp, CancellationToken.None);
|
||||||
|
|
||||||
Assert.IsFalse(sm.CheckSubscriptions("A/B/X", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
Assert.IsFalse(sm.CheckSubscriptions("A/B/X", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
||||||
}
|
}
|
||||||
@@ -89,13 +90,13 @@ namespace MQTTnet.Tests.Server
|
|||||||
var sp = new MqttSubscribePacket();
|
var sp = new MqttSubscribePacket();
|
||||||
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
sp.TopicFilters.Add(new MqttTopicFilterBuilder().WithTopic("A/B/C").Build());
|
||||||
|
|
||||||
await sm.Subscribe(sp);
|
await sm.Subscribe(sp, CancellationToken.None);
|
||||||
|
|
||||||
Assert.IsTrue(sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
Assert.IsTrue(sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
||||||
|
|
||||||
var up = new MqttUnsubscribePacket();
|
var up = new MqttUnsubscribePacket();
|
||||||
up.TopicFilters.Add("A/B/C");
|
up.TopicFilters.Add("A/B/C");
|
||||||
await sm.Unsubscribe(up);
|
await sm.Unsubscribe(up, CancellationToken.None);
|
||||||
|
|
||||||
Assert.IsFalse(sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
Assert.IsFalse(sm.CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "").IsSubscribed);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user