Files
chesscubing/ChessCubing.Server/Social/ConnectedUserTracker.cs

61 lines
1.8 KiB
C#

namespace ChessCubing.Server.Social;
public sealed class ConnectedUserTracker
{
private readonly object _sync = new();
private readonly Dictionary<string, string> _subjectByConnection = new(StringComparer.Ordinal);
private readonly Dictionary<string, HashSet<string>> _connectionsBySubject = new(StringComparer.Ordinal);
public bool TrackConnection(string connectionId, string subject)
{
lock (_sync)
{
_subjectByConnection[connectionId] = subject;
if (!_connectionsBySubject.TryGetValue(subject, out var connections))
{
connections = new HashSet<string>(StringComparer.Ordinal);
_connectionsBySubject[subject] = connections;
}
var wasOffline = connections.Count == 0;
connections.Add(connectionId);
return wasOffline;
}
}
public (string? Subject, bool BecameOffline) RemoveConnection(string connectionId)
{
lock (_sync)
{
if (!_subjectByConnection.Remove(connectionId, out var subject))
{
return (null, false);
}
if (!_connectionsBySubject.TryGetValue(subject, out var connections))
{
return (subject, false);
}
connections.Remove(connectionId);
if (connections.Count > 0)
{
return (subject, false);
}
_connectionsBySubject.Remove(subject);
return (subject, true);
}
}
public bool IsOnline(string subject)
{
lock (_sync)
{
return _connectionsBySubject.TryGetValue(subject, out var connections)
&& connections.Count > 0;
}
}
}