2025-11-16 19:16:44 +08:00

158 lines
6.0 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 CrasyStudio.Core.Common.Redis.Dto;
using CrasyStudio.Core.Common.Status;
using CrasyStudio.Core.Common.Status.Eitities;
using Fleck;
using MessagePack;
using NanoidDotNet;
namespace CGamesServer.Api.WebServers
{
public class GameServer
{
//private const int BufferSize = 1024;
//private HttpListener _httpListener;
//private bool isRunning = false;
//public GameServer(string domain)
//{
// _httpListener = new HttpListener();
// _httpListener.Prefixes.Add(domain);
//}
//public async Task Start()
//{
// this.isRunning = true;
// _httpListener.Start();
// Console.WriteLine($"WebSocket server started. Listening on {_httpListener.Prefixes.FirstOrDefault()}");
// while (isRunning)
// {
// var context = await _httpListener.GetContextAsync();
// if (context.Request.IsWebSocketRequest)
// {
// var webSocketContext = await context.AcceptWebSocketAsync(null);
// await HandleWebSocketConnection(webSocketContext.WebSocket);
// }
// else
// {
// context.Response.StatusCode = 400;
// context.Response.Close();
// }
// }
//}
//public void Stop()
//{
// this.isRunning = false;
// _httpListener.Stop();
// Console.WriteLine("WebSocket server stopped.");
//}
//private async Task HandleWebSocketConnection(WebSocket webSocket)
//{
// var buffer = new byte[BufferSize];
// var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
// while (!receiveResult.CloseStatus.HasValue)
// {
// var message = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
// Console.WriteLine($"Received: {message}");
// var responseMessage = $"Server received: {message}";
// var responseBuffer = Encoding.UTF8.GetBytes(responseMessage);
// await webSocket.SendAsync(new ArraySegment<byte>(responseBuffer), WebSocketMessageType.Text, true, CancellationToken.None);
// receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
// }
// await webSocket.CloseAsync(receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None);
//}
private readonly ClusterOnlineUsers _onlineUsers;
private readonly NetEventRegister _netEventRegister;
public GameServer(ClusterOnlineUsers onlineUsers, NetEventRegister netEventRegister)
{
this._onlineUsers = onlineUsers;
this._netEventRegister = netEventRegister;
}
public void Start(int webServerPort)
{
FleckLog.Level = Fleck.LogLevel.Error;
// 启动Fleck WebSocket服务器独立线程
var webSocketServer = new WebSocketServer($"ws://0.0.0.0:{webServerPort}");
//var webSocketServer = new WebSocketServer($"wss://0.0.0.0:{webServerPort}");
//webSocketServer.Certificate = new X509Certificate2("MyCert.pfx");
webSocketServer.ListenerSocket.NoDelay = true;//禁用Nagle算法增加实时性但是会使流量变大适合小包高频率发送
webSocketServer.Start(InitWebSocketConnection);
}
public void InitWebSocketConnection(IWebSocketConnection socket)
{
int checkDisconnectForHeartBeatCount = 0;
var user = new OnlineUserInfo
{
Socket = socket
};
Timer heartBeatTimer = new Timer((state) =>
{
if (user.HeartBeatDurationMs == -1)
{
return;
}
checkDisconnectForHeartBeatCount++;
if (checkDisconnectForHeartBeatCount > 3)
{
socket.Close();
//Console.WriteLine($"心跳包超时,关闭连接: {socket.ConnectionInfo.ClientIpAddress}");
}
});
//这里生成ConnectionId
string connectionId = Nanoid.Generate(); //Guid.NewGuid().ToString("N");
socket.OnOpen = async () =>
{
heartBeatTimer.Change(0, 1000);
//Console.WriteLine("WebSocket连接建立");
await _onlineUsers.AddOrUpdateUser(connectionId, user);
};
socket.OnClose = async () =>
{
heartBeatTimer.Dispose();
user.HeartBeatDurationMs = -1;//连接断开,修正心跳包检测时间为不需要
await _onlineUsers.RemoveUserFromId(connectionId);
//Console.WriteLine("WebSocket连接关闭");
};
socket.OnError = (ex) =>
{
//await _onlineUsers.RemoveUserFromId(connectionId);
//Console.WriteLine("WebSocket错误:" + ex.Message + ":StackTrace:" + ex.StackTrace);
};
socket.OnBinary = async message =>
{
checkDisconnectForHeartBeatCount = 0;
//Console.WriteLine($"收到消息: {message}");
try
{
var baseMessage = MessagePackSerializer.Deserialize<BaseMessage>(message);
await _netEventRegister.InvokeEvent(baseMessage.MsgType, connectionId, baseMessage);
}
catch (MessagePackSerializationException ex)
{
Console.WriteLine($"反序列化消息错误: {ex.Message}");
socket.Close();
}
//socket.Send(message); // 回显消息
};
socket.OnMessage = (message) =>
{
checkDisconnectForHeartBeatCount = 0;
};
}
}
}