|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
using Connected.Collections;
|
|
|
|
|
|
|
|
|
|
namespace Connected.Net.Hubs;
|
|
|
|
|
|
|
|
|
|
public sealed class ClientMessages<TArgs>
|
|
|
|
|
{
|
|
|
|
|
private readonly ConcurrentDictionary<string, Messages<TArgs>> _clients;
|
|
|
|
|
public ClientMessages()
|
|
|
|
|
{
|
|
|
|
|
_clients = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
}
|
|
|
|
|
private ConcurrentDictionary<string, Messages<TArgs>> Clients => _clients;
|
|
|
|
|
public void Clean()
|
|
|
|
|
{
|
|
|
|
|
foreach (var client in Clients)
|
|
|
|
|
{
|
|
|
|
|
client.Value.Scave();
|
|
|
|
|
|
|
|
|
|
if (client.Value.IsEmpty)
|
|
|
|
|
Clients.TryRemove(client.Key, out _);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public ImmutableList<Message<TArgs>> Dequeue()
|
|
|
|
|
{
|
|
|
|
|
var result = new List<Message<TArgs>>();
|
|
|
|
|
|
|
|
|
|
foreach (var client in Clients)
|
|
|
|
|
{
|
|
|
|
|
var items = client.Value.Dequeue();
|
|
|
|
|
|
|
|
|
|
if (!items.IsEmpty)
|
|
|
|
|
result.AddRange(items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.ToImmutableList(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Remove(string connectionId)
|
|
|
|
|
{
|
|
|
|
|
foreach (var client in Clients)
|
|
|
|
|
{
|
|
|
|
|
client.Value.Remove(connectionId);
|
|
|
|
|
|
|
|
|
|
if (client.Value.IsEmpty)
|
|
|
|
|
Clients.TryRemove(client.Key, out _);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Remove(string connection, IMessageAcknowledgeArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!Clients.TryGetValue(connection, out Messages<TArgs>? items))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
items.Remove(e.Id);
|
|
|
|
|
|
|
|
|
|
if (items.IsEmpty)
|
|
|
|
|
Clients.TryRemove(connection, out _);
|
|
|
|
|
}
|
|
|
|
|
public void Remove(string connection, string key)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(connection))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!Clients.TryGetValue(connection, out Messages<TArgs>? items))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
items.Remove(connection, key);
|
|
|
|
|
|
|
|
|
|
if (items.IsEmpty)
|
|
|
|
|
Clients.Remove(connection, out _);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Add(string client, Message<TArgs> message)
|
|
|
|
|
{
|
|
|
|
|
if (!Clients.TryGetValue(client, out Messages<TArgs>? items))
|
|
|
|
|
{
|
|
|
|
|
items = new Messages<TArgs>();
|
|
|
|
|
|
|
|
|
|
if (!Clients.TryAdd(client, items))
|
|
|
|
|
Clients.TryGetValue(client, out items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items.Add(message);
|
|
|
|
|
}
|
|
|
|
|
}
|