using System.Collections.Concurrent; using System.Net.WebSockets; using JNPF.Extras.WebSockets.Models; namespace JNPF.WebSockets; /// /// WebSocket 连接管理. /// public class WebSocketConnectionManager { /// /// 全部 socket 池. /// private ConcurrentDictionary _sockets = new ConcurrentDictionary(); /// /// 用户组 socket 池. /// private ConcurrentDictionary> _users = new ConcurrentDictionary>(); /// /// 租户组 socket 池. /// private ConcurrentDictionary> _tenant = new ConcurrentDictionary>(); /// /// 获取指定 id 的 socket. /// /// /// public WebSocketClient GetSocketById(string id) { if (_sockets.TryGetValue(id, out WebSocketClient socket)) return socket; else return null; } /// /// 获取全部socket. /// /// public ConcurrentDictionary GetAll() { return _sockets; } /// /// 获取租户组内全部socket. /// /// /// public List GetAllFromTenant(string tenantID) { if (_tenant.ContainsKey(tenantID)) { return _tenant[tenantID]; } return default; } /// /// 获取用户组内全部socket. /// /// /// public List GetAllFromUser(string userID) { if (_users.ContainsKey(userID)) { return _users[userID]; } return default; } /// /// 根据 socket 获取其 id. /// /// /// public string GetId(WebSocket socket) { return _sockets.FirstOrDefault(p => p.Value.WebSocket == socket).Key; } /// /// 添加无连接ID socket. /// /// public void AddSocket(WebSocketClient socket) { _sockets.TryAdd(CreateConnectionId(), socket); } /// /// 添加带连接 id socket. /// /// /// public void AddSocket(string socketID, WebSocketClient socket) { _sockets.TryAdd(socketID, socket); } /// /// 将连接添加至租户组. /// /// /// public void AddToTenant(string socketID, string tenantID) { if (_tenant.ContainsKey(tenantID)) { if (!_tenant[tenantID].Contains(socketID)) _tenant[tenantID].Add(socketID); return; } _tenant.TryAdd(tenantID, new List { socketID }); } /// /// 移除租户内某个连接. /// /// /// public void RemoveFromTenant(string socketID, string tenantID) { if (_tenant.ContainsKey(tenantID)) { _tenant[tenantID].Remove(socketID); } } /// /// 将连接添加至用户组 /// 用户可以多端登录. /// /// /// 格式为租户ID+用户ID. public void AddToUser(string socketID, string userID) { if (_users.ContainsKey(userID)) { if (!_users[userID].Contains(socketID)) _users[userID].Add(socketID); return; } _users.TryAdd(userID, new List { socketID }); } /// /// 移除用户组内某个连接. /// /// /// 格式为租户ID+用户ID. public void RemoveFromUser(string socketID, string userID) { if (_users.ContainsKey(userID)) { _users[userID].Remove(socketID); } } /// /// 移除某个 socket. /// /// /// public async Task RemoveSocket(string id) { if (id == null) return; if (_sockets.TryRemove(id, out WebSocketClient client)) { if (client.WebSocket.State != WebSocketState.Open) return; await client.WebSocket.CloseAsync(closeStatus: WebSocketCloseStatus.NormalClosure, statusDescription: "Closed by the WebSocketManager", cancellationToken: CancellationToken.None).ConfigureAwait(false); } } /// /// 生成连接ID. /// /// private string CreateConnectionId() { return Guid.NewGuid().ToString(); } /// /// 获取全部客户端数量. /// /// public int GetSocketClientCount() { return _sockets.Count(); } /// /// 返回用户组客户端数量. /// /// /// public int GetSocketClientToUserCount(string userID) { if (_users.ContainsKey(userID)) return _users[userID].Count(); return 0; } }