using System.Collections.Concurrent; using System.Net.WebSockets; namespace Tiger.Networking.Game.Sessions; public class GameSessionManager : IGameSessionManager { private readonly ConcurrentDictionary _sessions = new(); public GameSession AddSession(WebSocket webSocket) { var sessionId = Guid.NewGuid().ToString(); var gameSession = new GameSession(webSocket, sessionId); _sessions.TryAdd(sessionId, gameSession); return gameSession; } public void RemoveSession(WebSocket webSocket) { var session = GetSession(webSocket); if (session != null) { _sessions.TryRemove(session.SessionId, out _); } } public void CloseAll() { foreach (var session in _sessions.Values) { session.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server shutdown", CancellationToken.None); } } public GameSession? GetSession(WebSocket webSocket) { return (from session in _sessions where session.Value.WebSocket == webSocket select session.Value).FirstOrDefault(); } public GameSession? GetSession(string sessionId) { return _sessions.TryGetValue(sessionId, out var gameSession) ? gameSession : null; } public async Task CloseAsync(string reason, GameSession session) { if (_sessions.TryGetValue(session.SessionId, out var gameSession)) { if (gameSession.WebSocket.State == WebSocketState.Open) { await gameSession.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, reason, CancellationToken.None); } _sessions.TryRemove(session.SessionId, out _); } } }