mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-20 03:24:33 +08:00
1612 mqttserver subscription to similar base and subtopic with wildcards fails (#1622)
This commit is contained in:
@@ -55,18 +55,21 @@ namespace MQTTnet.Server
|
||||
{
|
||||
if (_noWildcardSubscriptionsByTopicHash.TryGetValue(topicHash, out var noWildcardSubscriptions))
|
||||
{
|
||||
possibleSubscriptions.AddRange(noWildcardSubscriptions.ToList());
|
||||
possibleSubscriptions.AddRange(noWildcardSubscriptions);
|
||||
}
|
||||
|
||||
foreach (var wcs in _wildcardSubscriptionsByTopicHash)
|
||||
{
|
||||
var wildcardSubscriptions = wcs.Value;
|
||||
var subscriptionHash = wcs.Key;
|
||||
var subscriptionHashMask = wildcardSubscriptions.HashMask;
|
||||
|
||||
if ((topicHash & subscriptionHashMask) == subscriptionHash)
|
||||
var subscriptionsByHashMask = wcs.Value.SubscriptionsByHashMask;
|
||||
foreach (var shm in subscriptionsByHashMask)
|
||||
{
|
||||
possibleSubscriptions.AddRange(wildcardSubscriptions.Subscriptions.ToList());
|
||||
var subscriptionHashMask = shm.Key;
|
||||
if ((topicHash & subscriptionHashMask) == subscriptionHash)
|
||||
{
|
||||
var subscriptions = shm.Value;
|
||||
possibleSubscriptions.AddRange(subscriptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,8 +268,8 @@ namespace MQTTnet.Server
|
||||
{
|
||||
if (_wildcardSubscriptionsByTopicHash.TryGetValue(topicHash, out var subscriptions))
|
||||
{
|
||||
subscriptions.Subscriptions.Remove(existingSubscription);
|
||||
if (subscriptions.Subscriptions.Count == 0)
|
||||
subscriptions.RemoveSubscription(existingSubscription);
|
||||
if (subscriptions.SubscriptionsByHashMask.Count == 0)
|
||||
{
|
||||
_wildcardSubscriptionsByTopicHash.Remove(topicHash);
|
||||
}
|
||||
@@ -346,9 +349,9 @@ namespace MQTTnet.Server
|
||||
// must remove object from topic hash dictionary first
|
||||
if (hasWildcard)
|
||||
{
|
||||
if (_wildcardSubscriptionsByTopicHash.TryGetValue(topicHash, out var subs))
|
||||
if (_wildcardSubscriptionsByTopicHash.TryGetValue(topicHash, out var subscriptions))
|
||||
{
|
||||
subs.Subscriptions.Remove(existingSubscription);
|
||||
subscriptions.RemoveSubscription(existingSubscription);
|
||||
// no need to remove empty entry because we'll be adding subscription again below
|
||||
}
|
||||
}
|
||||
@@ -370,11 +373,11 @@ namespace MQTTnet.Server
|
||||
{
|
||||
if (!_wildcardSubscriptionsByTopicHash.TryGetValue(topicHash, out var subscriptions))
|
||||
{
|
||||
subscriptions = new TopicHashMaskSubscriptions(topicHashMask);
|
||||
subscriptions = new TopicHashMaskSubscriptions();
|
||||
_wildcardSubscriptionsByTopicHash.Add(topicHash, subscriptions);
|
||||
}
|
||||
|
||||
subscriptions.Subscriptions.Add(subscription);
|
||||
subscriptions.AddSubscription(subscription);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -3,17 +3,32 @@ using System.Collections.Generic;
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class that stores the topic hash mask common to all contained Subscriptions for direct access.
|
||||
/// Helper class that stores subscriptions by their topic hash mask.
|
||||
/// </summary>
|
||||
public sealed class TopicHashMaskSubscriptions
|
||||
{
|
||||
public TopicHashMaskSubscriptions(ulong hashMask)
|
||||
public Dictionary<ulong, HashSet<MqttSubscription>> SubscriptionsByHashMask { get; } = new Dictionary<ulong, HashSet<MqttSubscription>>();
|
||||
|
||||
public void AddSubscription(MqttSubscription subscription)
|
||||
{
|
||||
HashMask = hashMask;
|
||||
if (!SubscriptionsByHashMask.TryGetValue(subscription.TopicHashMask, out var subscriptions))
|
||||
{
|
||||
subscriptions = new HashSet<MqttSubscription>();
|
||||
SubscriptionsByHashMask.Add(subscription.TopicHashMask, subscriptions);
|
||||
}
|
||||
subscriptions.Add(subscription);
|
||||
}
|
||||
|
||||
public ulong HashMask { get; }
|
||||
|
||||
public HashSet<MqttSubscription> Subscriptions { get; } = new HashSet<MqttSubscription>();
|
||||
public void RemoveSubscription(MqttSubscription subscription)
|
||||
{
|
||||
if (SubscriptionsByHashMask.TryGetValue(subscription.TopicHashMask, out var subscriptions))
|
||||
{
|
||||
subscriptions.Remove(subscription);
|
||||
if (subscriptions.Count == 0)
|
||||
{
|
||||
SubscriptionsByHashMask.Remove(subscription.TopicHashMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user