fix(lmxproxy): fix orphaned tag subscriptions when client subscribes per-tag
When a client calls Subscribe multiple times with the same session ID (one tag per RPC), each call overwrites the ClientSubscription entry. UnsubscribeClient only cleaned up tags from the last entry, leaving earlier tags orphaned in _tagSubscriptions. Now scans all tag subscriptions for client references during cleanup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,8 +57,8 @@ namespace ZB.MOM.WW.LmxProxy.Host.Subscriptions
|
||||
});
|
||||
|
||||
var addressSet = new HashSet<string>(addresses, StringComparer.OrdinalIgnoreCase);
|
||||
var clientSub = new ClientSubscription(clientId, channel, addressSet);
|
||||
|
||||
var clientSub = new ClientSubscription(clientId, channel, addressSet);
|
||||
_clientSubscriptions[clientId] = clientSub;
|
||||
|
||||
var newTags = new List<string>();
|
||||
@@ -170,17 +170,18 @@ namespace ZB.MOM.WW.LmxProxy.Host.Subscriptions
|
||||
_rwLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
foreach (var address in clientSub.Addresses)
|
||||
// Scan all tag subscriptions — not just clientSub.Addresses — because
|
||||
// a client may have called Subscribe multiple times (one tag per RPC),
|
||||
// each overwriting the ClientSubscription. The last one's Addresses
|
||||
// only has the final batch, but earlier tags still reference this client.
|
||||
foreach (var kvp in _tagSubscriptions)
|
||||
{
|
||||
if (_tagSubscriptions.TryGetValue(address, out var tagSub))
|
||||
if (kvp.Value.ClientIds.Remove(clientId))
|
||||
{
|
||||
tagSub.ClientIds.Remove(clientId);
|
||||
|
||||
// Last client unsubscribed — remove the tag subscription
|
||||
if (tagSub.ClientIds.Count == 0)
|
||||
if (kvp.Value.ClientIds.Count == 0)
|
||||
{
|
||||
_tagSubscriptions.TryRemove(address, out _);
|
||||
tagsToDispose.Add(address);
|
||||
_tagSubscriptions.TryRemove(kvp.Key, out _);
|
||||
tagsToDispose.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user