Files
Relay/RelayServer/Services/Chat/ConnectedClientService.cs
RuKira dd75ca4b06 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	RelayClient/MainPage.xaml.cs
#	RelayClient/Services/RelaySocketClient.cs
#	RelayServer/Services/Chat/ChatSocketBehavior.cs
#	RelayServer/Services/Chat/ConnectedClientService.cs
#	RelayShared/Services/WsControlMessage.cs
2026-06-03 13:20:15 -04:00

63 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 _);
}
}
}