mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-20 11:45:43 +08:00
Add support for topic alias.
This commit is contained in:
@@ -219,7 +219,7 @@ namespace MQTTnet.Client
|
||||
{
|
||||
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
||||
|
||||
MqttTopicValidator.ThrowIfInvalid(applicationMessage.Topic);
|
||||
MqttTopicValidator.ThrowIfInvalid(applicationMessage);
|
||||
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotConnected();
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace MQTTnet.Formatter
|
||||
|
||||
MqttPubAckPacket CreatePubAckPacket(MqttPublishPacket publishPacket);
|
||||
|
||||
MqttBasePacket CreatePubRecPacket(MqttPublishPacket publishPacket);
|
||||
|
||||
MqttApplicationMessage CreateApplicationMessage(MqttPublishPacket publishPacket);
|
||||
|
||||
MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket);
|
||||
|
||||
@@ -40,6 +40,15 @@ namespace MQTTnet.Formatter.V3
|
||||
};
|
||||
}
|
||||
|
||||
public MqttBasePacket CreatePubRecPacket(MqttPublishPacket publishPacket)
|
||||
{
|
||||
return new MqttPubRecPacket
|
||||
{
|
||||
PacketIdentifier = publishPacket.PacketIdentifier,
|
||||
ReasonCode = MqttPubRecReasonCode.Success
|
||||
};
|
||||
}
|
||||
|
||||
public MqttApplicationMessage CreateApplicationMessage(MqttPublishPacket publishPacket)
|
||||
{
|
||||
if (publishPacket == null) throw new ArgumentNullException(nameof(publishPacket));
|
||||
|
||||
@@ -58,6 +58,15 @@ namespace MQTTnet.Formatter.V5
|
||||
};
|
||||
}
|
||||
|
||||
public MqttBasePacket CreatePubRecPacket(MqttPublishPacket publishPacket)
|
||||
{
|
||||
return new MqttPubRecPacket
|
||||
{
|
||||
PacketIdentifier = publishPacket.PacketIdentifier,
|
||||
ReasonCode = MqttPubRecReasonCode.Success
|
||||
};
|
||||
}
|
||||
|
||||
public MqttApplicationMessage CreateApplicationMessage(MqttPublishPacket publishPacket)
|
||||
{
|
||||
return new MqttApplicationMessage
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
using MQTTnet.Exceptions;
|
||||
using System;
|
||||
using MQTTnet.Exceptions;
|
||||
|
||||
namespace MQTTnet.Protocol
|
||||
{
|
||||
public static class MqttTopicValidator
|
||||
{
|
||||
public static void ThrowIfInvalid(MqttApplicationMessage applicationMessage)
|
||||
{
|
||||
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
||||
|
||||
if (applicationMessage.TopicAlias > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ThrowIfInvalid(applicationMessage.Topic);
|
||||
}
|
||||
|
||||
public static void ThrowIfInvalid(string topic)
|
||||
{
|
||||
if (string.IsNullOrEmpty(topic))
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace MQTTnet.Server
|
||||
{
|
||||
public sealed class MqttClientConnection : IDisposable
|
||||
{
|
||||
readonly Dictionary<ushort, string> _topicAlias = new Dictionary<ushort, string>();
|
||||
readonly MqttPacketIdentifierProvider _packetIdentifierProvider = new MqttPacketIdentifierProvider();
|
||||
readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
|
||||
readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource();
|
||||
@@ -316,19 +317,26 @@ namespace MQTTnet.Server
|
||||
{
|
||||
Interlocked.Increment(ref _sentApplicationMessagesCount);
|
||||
|
||||
HandleTopicAlias(publishPacket);
|
||||
|
||||
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
|
||||
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
|
||||
|
||||
switch (publishPacket.QualityOfServiceLevel)
|
||||
{
|
||||
case MqttQualityOfServiceLevel.AtMostOnce:
|
||||
{
|
||||
return HandleIncomingPublishPacketWithQoS0Async(publishPacket);
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
}
|
||||
case MqttQualityOfServiceLevel.AtLeastOnce:
|
||||
{
|
||||
return HandleIncomingPublishPacketWithQoS1Async(publishPacket, cancellationToken);
|
||||
var pubAckPacket = _dataConverter.CreatePubAckPacket(publishPacket);
|
||||
return SendAsync(pubAckPacket, cancellationToken);
|
||||
}
|
||||
case MqttQualityOfServiceLevel.ExactlyOnce:
|
||||
{
|
||||
return HandleIncomingPublishPacketWithQoS2Async(publishPacket, cancellationToken);
|
||||
var pubRecPacket = _dataConverter.CreatePubRecPacket(publishPacket);
|
||||
return SendAsync(pubRecPacket, cancellationToken);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -337,36 +345,33 @@ namespace MQTTnet.Server
|
||||
}
|
||||
}
|
||||
|
||||
Task HandleIncomingPublishPacketWithQoS0Async(MqttPublishPacket publishPacket)
|
||||
void HandleTopicAlias(MqttPublishPacket publishPacket)
|
||||
{
|
||||
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
|
||||
|
||||
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
|
||||
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
}
|
||||
|
||||
Task HandleIncomingPublishPacketWithQoS1Async(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||
{
|
||||
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
|
||||
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
|
||||
|
||||
var pubAckPacket = _dataConverter.CreatePubAckPacket(publishPacket);
|
||||
return SendAsync(pubAckPacket, cancellationToken);
|
||||
}
|
||||
|
||||
Task HandleIncomingPublishPacketWithQoS2Async(MqttPublishPacket publishPacket, CancellationToken cancellationToken)
|
||||
{
|
||||
var applicationMessage = _dataConverter.CreateApplicationMessage(publishPacket);
|
||||
_sessionsManager.DispatchApplicationMessage(applicationMessage, this);
|
||||
|
||||
var pubRecPacket = new MqttPubRecPacket
|
||||
if (publishPacket.Properties?.TopicAlias == null)
|
||||
{
|
||||
PacketIdentifier = publishPacket.PacketIdentifier,
|
||||
ReasonCode = MqttPubRecReasonCode.Success
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
return SendAsync(pubRecPacket, cancellationToken);
|
||||
var topicAlias = publishPacket.Properties.TopicAlias.Value;
|
||||
|
||||
lock (_topicAlias)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(publishPacket.Topic))
|
||||
{
|
||||
_topicAlias[topicAlias] = publishPacket.Topic;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_topicAlias.TryGetValue(topicAlias, out var topic))
|
||||
{
|
||||
publishPacket.Topic = topic;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async Task SendPendingPacketsAsync(CancellationToken cancellationToken)
|
||||
|
||||
Reference in New Issue
Block a user