64 lines
1.9 KiB
C#
64 lines
1.9 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
namespace RelayServer.Services.Chat;
|
|
|
|
public static class ConnectedClientService
|
|
{
|
|
private static readonly ConcurrentDictionary<string, string> SessionToUsername = new();
|
|
private static readonly ConcurrentDictionary<string, HashSet<string>> UsernameToSessions =
|
|
new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
public static void Register(string sessionId, string username)
|
|
{
|
|
if (SessionToUsername.TryGetValue(sessionId, out var oldUsername) &&
|
|
!string.Equals(oldUsername, username, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
RemoveSessionFromUsername(sessionId, oldUsername);
|
|
}
|
|
|
|
SessionToUsername[sessionId] = username;
|
|
|
|
var sessions = UsernameToSessions.GetOrAdd(
|
|
username,
|
|
_ => new HashSet<string>(StringComparer.Ordinal));
|
|
|
|
lock (sessions)
|
|
sessions.Add(sessionId);
|
|
}
|
|
|
|
public static void Unregister(string sessionId)
|
|
{
|
|
if (SessionToUsername.TryRemove(sessionId, out var username))
|
|
RemoveSessionFromUsername(sessionId, username);
|
|
}
|
|
|
|
public static IReadOnlyCollection<string> GetSessionsForUser(string username)
|
|
{
|
|
if (UsernameToSessions.TryGetValue(username, out var sessions))
|
|
{
|
|
lock (sessions)
|
|
return sessions.ToList();
|
|
}
|
|
|
|
return Array.Empty<string>();
|
|
}
|
|
|
|
public static string? GetUsernameForSession(string sessionId)
|
|
{
|
|
return SessionToUsername.TryGetValue(sessionId, out var u) ? u : null;
|
|
}
|
|
|
|
private static void RemoveSessionFromUsername(string sessionId, string username)
|
|
{
|
|
if (!UsernameToSessions.TryGetValue(username, out var sessions))
|
|
return;
|
|
|
|
lock (sessions)
|
|
{
|
|
sessions.Remove(sessionId);
|
|
if (sessions.Count == 0)
|
|
UsernameToSessions.TryRemove(username, out _);
|
|
}
|
|
}
|
|
}
|