61 lines
1.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|