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;
}
}