XNet/XNet.Business/Net/WsServer.cs
2025-12-31 18:29:29 +08:00

87 lines
3.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using MessagePack;
using System.Net.WebSockets;
using XNet.Business.PathNavigation;
using XNet.Business.Tank.Manager;
namespace XNet.Business.Net
{
public static class WsServer
{
private static ActionManager? ActionManager = null;
// 启动WebSocket监听
public static void MapWebSocketServer(this WebApplication app, WsConnectionManager wsManager, NavMeshManager navMeshManager, SceneAgent sceneAgent)
{
if (ActionManager == null)
{
ActionManager = new ActionManager(wsManager, navMeshManager, sceneAgent);
}
//初始化玩家设备列表
DeviceManager.Instance.Init();
app.Map("/ws", async context =>
{
if (!context.WebSockets.IsWebSocketRequest)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
return;
}
// 建立WebSocket连接
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
string connId = wsManager.AddConnection(webSocket);
// 【修改点1】单条消息的缓冲区用MemoryStream接收分片数据自动扩容
var receiveBuffer = new byte[1024 * 4];
var ms = new MemoryStream();
try
{
while (webSocket.State == WebSocketState.Open)
{
var result = await webSocket.ReceiveAsync(receiveBuffer, CancellationToken.None);
// 1. 客户端主动关闭连接
if (result.MessageType == WebSocketMessageType.Close)
{
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", CancellationToken.None);
await wsManager.RemoveConnection(connId);
break;
}
// 2. 忽略空消息/心跳包
if (result.Count == 0) continue;
// 3. 【核心修复】将本次收到的分片数据写入MemoryStream拼接完整消息
ms.Write(receiveBuffer, 0, result.Count);
// 4. 【核心修复】判断是否是完整消息的最后分片
if (result.EndOfMessage)
{
// 重置流的指针到起始位置,准备反序列化
ms.Position = 0;
byte[] data1 = ms.ToArray();
// 反序列化完整的消息
var wsMsg = MessagePackSerializer.Deserialize<BaseMsg>(data1);
if (wsMsg != null)
{
// 执行你的业务逻辑,异步无等待
_ = ActionManager.ExecuteAction(wsMsg.Type, connId, wsMsg.Data!);
}
// 清空流,准备接收下一条消息
ms.SetLength(0);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"[WS] 连接 {connId} 异常:{ex.Message}");
}
finally
{
// 释放资源 + 移除连接
ms.Dispose();
await wsManager.RemoveConnection(connId);
}
});
}
}
}