`
This commit is contained in:
parent
fd60b1cea5
commit
84d98d54d4
11
XNet.Business/Entity/WebSocketInfo.cs
Normal file
11
XNet.Business/Entity/WebSocketInfo.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
|
||||||
|
namespace XNet.Business.Entity
|
||||||
|
{
|
||||||
|
public class WebSocketInfo
|
||||||
|
{
|
||||||
|
public WebSocket WebSocket { get; set; } = null!;
|
||||||
|
public ConcurrentDictionary<string, bool> RoomIds { get; set; } = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ using System.Diagnostics;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using XNet.Business.Entity;
|
||||||
using XNet.Business.PathNavigation;
|
using XNet.Business.PathNavigation;
|
||||||
|
|
||||||
namespace XNet.Business.Net
|
namespace XNet.Business.Net
|
||||||
@ -13,7 +14,7 @@ namespace XNet.Business.Net
|
|||||||
public class WsConnectionManager
|
public class WsConnectionManager
|
||||||
{
|
{
|
||||||
// ========== 原有核心字段 ==========
|
// ========== 原有核心字段 ==========
|
||||||
private readonly ConcurrentDictionary<string, WebSocket> _connections = new();
|
private readonly ConcurrentDictionary<string, WebSocketInfo> _connections = new();
|
||||||
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, bool>> _instanceSubscribers = new();
|
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, bool>> _instanceSubscribers = new();
|
||||||
//private readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
//private readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ namespace XNet.Business.Net
|
|||||||
private readonly ObjectPool<List<string>> _deadConnListPool;
|
private readonly ObjectPool<List<string>> _deadConnListPool;
|
||||||
private readonly ObjectPool<byte[]> _byteArrayPool;
|
private readonly ObjectPool<byte[]> _byteArrayPool;
|
||||||
|
|
||||||
private readonly SceneAgent _sceneAgent = null;
|
private readonly SceneAgent _sceneAgent = null!;
|
||||||
|
|
||||||
public WsConnectionManager(SceneAgent sceneAgent)
|
public WsConnectionManager(SceneAgent sceneAgent)
|
||||||
{
|
{
|
||||||
@ -41,16 +42,19 @@ namespace XNet.Business.Net
|
|||||||
public string AddConnection(WebSocket socket)
|
public string AddConnection(WebSocket socket)
|
||||||
{
|
{
|
||||||
string connId = $"Conn_{Nanoid.Generate()}";
|
string connId = $"Conn_{Nanoid.Generate()}";
|
||||||
_connections.TryAdd(connId, socket);
|
_connections.TryAdd(connId, new WebSocketInfo
|
||||||
|
{
|
||||||
|
WebSocket = socket
|
||||||
|
});
|
||||||
Console.WriteLine($"[WS .NET 10] 新连接:{connId},当前连接数:{_connections.Count}");
|
Console.WriteLine($"[WS .NET 10] 新连接:{connId},当前连接数:{_connections.Count}");
|
||||||
return connId;
|
return connId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveConnection(string connId)
|
public void RemoveConnection(string connId)
|
||||||
{
|
{
|
||||||
if (_connections.TryRemove(connId, out _))
|
if (_connections.TryRemove(connId, out var socketInfo))
|
||||||
{
|
{
|
||||||
foreach (var instanceId in _instanceSubscribers.Keys)
|
foreach (var instanceId in socketInfo.RoomIds.Keys)
|
||||||
{
|
{
|
||||||
_instanceSubscribers[instanceId].TryRemove(connId, out _);
|
_instanceSubscribers[instanceId].TryRemove(connId, out _);
|
||||||
|
|
||||||
@ -66,7 +70,7 @@ namespace XNet.Business.Net
|
|||||||
|
|
||||||
public bool SubscribeInstance(string connId, string mapKey, ref string roomId)
|
public bool SubscribeInstance(string connId, string mapKey, ref string roomId)
|
||||||
{
|
{
|
||||||
if (!_connections.ContainsKey(connId))
|
if (!_connections.TryGetValue(connId,out WebSocketInfo? socketInfo))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"[WS .NET 10] 订阅失败:连接 {connId} 不存在");
|
Console.WriteLine($"[WS .NET 10] 订阅失败:连接 {connId} 不存在");
|
||||||
return false;
|
return false;
|
||||||
@ -88,6 +92,8 @@ namespace XNet.Business.Net
|
|||||||
|
|
||||||
_instanceSubscribers[roomId].TryAdd(connId, true);
|
_instanceSubscribers[roomId].TryAdd(connId, true);
|
||||||
|
|
||||||
|
socketInfo.RoomIds[roomId] = true;
|
||||||
|
|
||||||
if (isNewInstance)
|
if (isNewInstance)
|
||||||
{
|
{
|
||||||
_sceneAgent.CreateInstance(roomId, mapKey);
|
_sceneAgent.CreateInstance(roomId, mapKey);
|
||||||
@ -107,7 +113,7 @@ namespace XNet.Business.Net
|
|||||||
|
|
||||||
public async Task SendSerializeMessageToPointWsSocket<T>(string connId, T syncMsgs)
|
public async Task SendSerializeMessageToPointWsSocket<T>(string connId, T syncMsgs)
|
||||||
{
|
{
|
||||||
if (_connections.TryGetValue(connId, out var socket))
|
if (_connections.TryGetValue(connId, out var socketInfo))
|
||||||
{
|
{
|
||||||
// 3. 复用:从池获取失效连接列表
|
// 3. 复用:从池获取失效连接列表
|
||||||
var deadConnIds = _deadConnListPool.Get();
|
var deadConnIds = _deadConnListPool.Get();
|
||||||
@ -117,12 +123,12 @@ namespace XNet.Business.Net
|
|||||||
if (msgBytesLength != 0)
|
if (msgBytesLength != 0)
|
||||||
{
|
{
|
||||||
// 3. 发送时传递有效长度
|
// 3. 发送时传递有效长度
|
||||||
_ = SendToSingleConnAsync(socket, msgBytes, msgBytesLength, connId, deadConnIds);
|
_ = SendToSingleConnAsync(socketInfo.WebSocket, msgBytes, msgBytesLength, connId, deadConnIds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 3. 发送整串字节数组
|
// 3. 发送整串字节数组
|
||||||
_ = SendToSingleConnAsync(socket, msgBytes, msgBytes.Length, connId, deadConnIds);
|
_ = SendToSingleConnAsync(socketInfo.WebSocket, msgBytes, msgBytes.Length, connId, deadConnIds);
|
||||||
}
|
}
|
||||||
// 清理失效连接
|
// 清理失效连接
|
||||||
foreach (var deadConnId in deadConnIds)
|
foreach (var deadConnId in deadConnIds)
|
||||||
@ -169,17 +175,17 @@ namespace XNet.Business.Net
|
|||||||
{
|
{
|
||||||
foreach (var connKv in subscriberConnIds)
|
foreach (var connKv in subscriberConnIds)
|
||||||
{
|
{
|
||||||
if (_connections.TryGetValue(connKv.Key, out var socket))
|
if (_connections.TryGetValue(connKv.Key, out var socketInfo))
|
||||||
{
|
{
|
||||||
if (msgBytesLength != 0)
|
if (msgBytesLength != 0)
|
||||||
{
|
{
|
||||||
// 3. 发送时传递有效长度
|
// 3. 发送时传递有效长度
|
||||||
_ = SendToSingleConnAsync(socket, msgBytes, msgBytesLength, connKv.Key, deadConnIds);
|
_ = SendToSingleConnAsync(socketInfo.WebSocket, msgBytes, msgBytesLength, connKv.Key, deadConnIds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 3. 发送整串字节数组
|
// 3. 发送整串字节数组
|
||||||
_ = SendToSingleConnAsync(socket, msgBytes, msgBytes.Length, connKv.Key, deadConnIds);
|
_ = SendToSingleConnAsync(socketInfo.WebSocket, msgBytes, msgBytes.Length, connKv.Key, deadConnIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,13 +290,14 @@ namespace XNet.Business.Net
|
|||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
foreach (var (_, socket) in _connections)
|
foreach (var (key, socketInfo) in _connections)
|
||||||
{
|
{
|
||||||
if (socket.State == WebSocketState.Open)
|
if (socketInfo.WebSocket.State == WebSocketState.Open)
|
||||||
{
|
{
|
||||||
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server shutdown", CancellationToken.None);
|
await socketInfo.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server shutdown", CancellationToken.None);
|
||||||
}
|
}
|
||||||
socket.Dispose();
|
socketInfo.WebSocket.Dispose();
|
||||||
|
RemoveConnection(key);
|
||||||
}
|
}
|
||||||
_connections.Clear();
|
_connections.Clear();
|
||||||
_instanceSubscribers.Clear();
|
_instanceSubscribers.Clear();
|
||||||
|
|||||||
@ -39,6 +39,7 @@ namespace XNet.Business.Net
|
|||||||
if (result.MessageType == WebSocketMessageType.Close)
|
if (result.MessageType == WebSocketMessageType.Close)
|
||||||
{
|
{
|
||||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", CancellationToken.None);
|
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", CancellationToken.None);
|
||||||
|
wsManager.RemoveConnection(connId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -136,6 +136,11 @@ namespace XNet.Business.PathNavigation
|
|||||||
_instanceMap.TryRemove(roomId, out _);
|
_instanceMap.TryRemove(roomId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearInstanceMap()
|
||||||
|
{
|
||||||
|
_instanceMap.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 3. 【新增】供 SceneAgent 使用的辅助方法
|
// 3. 【新增】供 SceneAgent 使用的辅助方法
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user