using System.Collections.Concurrent; namespace RelayServer.Services.Rtc; public static class RtcChannelPresenceService { private static readonly ConcurrentDictionary SessionToChannel = new(); private static readonly ConcurrentDictionary SessionToUsername = new(); public static void SetUser(string sessionId, string username) { SessionToUsername[sessionId] = username; } public static void JoinChannel(string sessionId, string channelId) { SessionToChannel[sessionId] = channelId; } public static void LeaveChannel(string sessionId) { SessionToChannel.TryRemove(sessionId, out _); } public static void RemoveSession(string sessionId) { SessionToChannel.TryRemove(sessionId, out _); SessionToUsername.TryRemove(sessionId, out _); } public static IReadOnlyList GetSessionsInChannel(string channelId) { return SessionToChannel .Where(x => x.Value == channelId) .Select(x => x.Key) .ToList(); } public static IReadOnlyList GetUsersInChannel(string channelId) { var sessionIds = GetSessionsInChannel(channelId); return sessionIds .Where(id => SessionToUsername.ContainsKey(id)) .Select(id => SessionToUsername[id]) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); } public static bool IsInChannel(string sessionId, string channelId) { return SessionToChannel.TryGetValue(sessionId, out var currentChannel) && string.Equals(currentChannel, channelId, StringComparison.Ordinal); } }