using System.Collections.Concurrent; using System.Collections.Immutable; namespace Connected.Net.Hubs; public sealed class Clients { public Clients() { Items = new(StringComparer.OrdinalIgnoreCase); } private ConcurrentDictionary> Items { get; set; } public void AddOrUpdate(Client client) { if (!Items.TryGetValue(client.Connection, out Client? existing)) { Items.TryAdd(client.Connection, client); return; } existing.RetentionDeadline = DateTime.MinValue; } public void Clean() { var dead = Items.Where(f => f.Value.RetentionDeadline != DateTime.MinValue && f.Value.RetentionDeadline <= DateTime.UtcNow).ToImmutableList(); if (dead.IsEmpty) return; foreach (var client in dead) Items.TryRemove(client.Key, out _); } public void Remove(string connectionId) { if (!Items.TryGetValue(connectionId, out Client? client)) return; if (client.Behavior == MessageClientBehavior.FireForget) Items.TryRemove(connectionId, out _); else client.RetentionDeadline = DateTime.UtcNow.AddMinutes(5); } public ImmutableList> Query() { return Items.Values.ToImmutableList(); } }