Feature/mqttv5 subscriptions server (#1246)

* Add support for RetainHandling.

* Add support for No Local.

* Add support for _SubscriptionIdentifier_.

* Add more Unit Tests.

* Update docs.
This commit is contained in:
Christian
2021-09-23 20:30:43 +02:00
committed by GitHub
parent feb53e78c6
commit c756a4092f
83 changed files with 2032 additions and 1237 deletions
@@ -1,34 +1,25 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MQTTnet.Diagnostics;
using MQTTnet.Server.Status;
namespace MQTTnet.Server.Internal
{
public sealed class MqttClientSession
{
readonly IMqttNetScopedLogger _logger;
readonly DateTime _createdTimestamp = DateTime.UtcNow;
readonly IMqttRetainedMessagesManager _retainedMessagesManager;
public MqttClientSession(
string clientId,
IDictionary<object, object> items,
MqttServerEventDispatcher eventDispatcher,
IMqttServerOptions serverOptions,
IMqttRetainedMessagesManager retainedMessagesManager,
IMqttNetLogger logger)
IMqttServerOptions serverOptions,
IMqttRetainedMessagesManager retainedMessagesManager)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
Items = items ?? throw new ArgumentNullException(nameof(items));
_retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
SubscriptionsManager = new MqttClientSubscriptionsManager(this, eventDispatcher, serverOptions);
ApplicationMessagesQueue = new MqttClientSessionApplicationMessagesQueue(serverOptions);
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateScopedLogger(nameof(MqttClientSession));
SubscriptionsManager = new MqttClientSubscriptionsManager(this, serverOptions, eventDispatcher, retainedMessagesManager);
ApplicationMessagesQueue = new MqttClientSessionApplicationMessagesQueue(serverOptions);
}
public string ClientId { get; }
@@ -45,42 +36,7 @@ namespace MQTTnet.Server.Internal
/// Gets or sets a key/value collection that can be used to share data within the scope of this session.
/// </summary>
public IDictionary<object, object> Items { get; }
public bool EnqueueApplicationMessage(MqttApplicationMessage applicationMessage, string senderClientId, bool isRetainedApplicationMessage)
{
var checkSubscriptionsResult = SubscriptionsManager.CheckSubscriptions(applicationMessage.Topic, applicationMessage.QualityOfServiceLevel);
if (!checkSubscriptionsResult.IsSubscribed)
{
return false;
}
_logger.Verbose("Client '{0}': Queued application message with topic '{1}'.", ClientId, applicationMessage.Topic);
ApplicationMessagesQueue.Enqueue(applicationMessage, senderClientId, checkSubscriptionsResult.QualityOfServiceLevel, isRetainedApplicationMessage);
return true;
}
public async Task SubscribeAsync(ICollection<MqttTopicFilter> topicFilters)
{
if (topicFilters is null) throw new ArgumentNullException(nameof(topicFilters));
await SubscriptionsManager.SubscribeAsync(topicFilters).ConfigureAwait(false);
var matchingRetainedMessages = await _retainedMessagesManager.GetSubscribedMessagesAsync(topicFilters).ConfigureAwait(false);
foreach (var matchingRetainedMessage in matchingRetainedMessages)
{
EnqueueApplicationMessage(matchingRetainedMessage, null, true);
}
}
public Task UnsubscribeAsync(IEnumerable<string> topicFilters)
{
if (topicFilters is null) throw new ArgumentNullException(nameof(topicFilters));
return SubscriptionsManager.UnsubscribeAsync(topicFilters);
}
public void FillSessionStatus(MqttSessionStatus status)
{
status.ClientId = ClientId;