Refactor subscriptions manager

This commit is contained in:
Christian
2018-05-03 22:22:07 +02:00
parent d14088512b
commit b22b02a0b6
12 changed files with 269 additions and 107 deletions
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -10,7 +11,7 @@ namespace MQTTnet.Server
{
public sealed class MqttClientSubscriptionsManager : IDisposable
{
private readonly Dictionary<string, MqttQualityOfServiceLevel> _subscriptions = new Dictionary<string, MqttQualityOfServiceLevel>();
private readonly ConcurrentDictionary<string, MqttQualityOfServiceLevel> _subscriptions = new ConcurrentDictionary<string, MqttQualityOfServiceLevel>();
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly IMqttServerOptions _options;
private readonly MqttServer _server;
@@ -23,7 +24,7 @@ namespace MQTTnet.Server
_server = server;
}
public async Task<MqttClientSubscribeResult> SubscribeAsync(MqttSubscribePacket subscribePacket)
public MqttClientSubscribeResult Subscribe(MqttSubscribePacket subscribePacket)
{
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
@@ -37,57 +38,41 @@ namespace MQTTnet.Server
CloseConnection = false
};
await _semaphore.WaitAsync().ConfigureAwait(false);
try
foreach (var topicFilter in subscribePacket.TopicFilters)
{
foreach (var topicFilter in subscribePacket.TopicFilters)
var interceptorContext = InterceptSubscribe(topicFilter);
if (!interceptorContext.AcceptSubscription)
{
var interceptorContext = InterceptSubscribe(topicFilter);
if (!interceptorContext.AcceptSubscription)
{
result.ResponsePacket.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.Failure);
}
else
{
result.ResponsePacket.SubscribeReturnCodes.Add(ConvertToMaximumQoS(topicFilter.QualityOfServiceLevel));
}
if (interceptorContext.CloseConnection)
{
result.CloseConnection = true;
}
if (interceptorContext.AcceptSubscription)
{
_subscriptions[topicFilter.Topic] = topicFilter.QualityOfServiceLevel;
_server.OnClientSubscribedTopic(_clientId, topicFilter);
}
result.ResponsePacket.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.Failure);
}
else
{
result.ResponsePacket.SubscribeReturnCodes.Add(ConvertToMaximumQoS(topicFilter.QualityOfServiceLevel));
}
if (interceptorContext.CloseConnection)
{
result.CloseConnection = true;
}
if (interceptorContext.AcceptSubscription)
{
_subscriptions[topicFilter.Topic] = topicFilter.QualityOfServiceLevel;
_server.OnClientSubscribedTopic(_clientId, topicFilter);
}
}
finally
{
_semaphore.Release();
}
return result;
}
public async Task<MqttUnsubAckPacket> UnsubscribeAsync(MqttUnsubscribePacket unsubscribePacket)
public MqttUnsubAckPacket Unsubscribe(MqttUnsubscribePacket unsubscribePacket)
{
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
await _semaphore.WaitAsync().ConfigureAwait(false);
try
foreach (var topicFilter in unsubscribePacket.TopicFilters)
{
foreach (var topicFilter in unsubscribePacket.TopicFilters)
{
_subscriptions.Remove(topicFilter);
_server.OnClientUnsubscribedTopic(_clientId, topicFilter);
}
}
finally
{
_semaphore.Release();
_subscriptions.TryRemove(topicFilter, out _);
_server.OnClientUnsubscribedTopic(_clientId, topicFilter);
}
return new MqttUnsubAckPacket