milimoe 940f8397f1
为服务器统一数据访问连接 (#91)
* 重做 WebSocket 监听;为服务器统一了多种数据连接访问时的处理;统一编码为 UTF-8

* ModelManager已更名并移动到工具命名空间中

* 完成 WebSocket 消息处理系统

* 添加Socket异步接收数据流;修复TaskUtility阻塞的问题;优化心跳、房间、模组

* 添加枚举

* 删除多余字符

* 添加监听器的名称

* 修改了命名
2024-10-02 15:00:34 +08:00

111 lines
3.7 KiB
C#

using Milimoe.FunGame.Core.Interface.Sockets;
using Milimoe.FunGame.Core.Library.Common.Network;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Library.Common.Architecture
{
public class HeartBeat : ISocketHeartBeat
{
public TransmittalType TransmittalType { get; } = TransmittalType.Socket;
public bool SendingHeartBeat => _SendingHeartBeat;
public int HeartBeatFaileds => _HeartBeatFaileds;
private Task? SendingHeartBeatTask;
private bool _SendingHeartBeat = false;
private bool _LastHeartbeatReceived = false;
private int _HeartBeatFaileds = 0;
private readonly Socket? _Socket = null;
private readonly HTTPClient? _HTTPClient = null;
public HeartBeat(Socket socket)
{
_Socket = socket;
TransmittalType = TransmittalType.Socket;
}
public HeartBeat(HTTPClient client)
{
_HTTPClient = client;
TransmittalType = TransmittalType.WebSocket;
}
public void StartSendingHeartBeat()
{
if (!FunGameInfo.FunGame_DebugMode)
{
_SendingHeartBeat = true;
_Socket?.AddSocketObjectHandler(SocketObject_Handler);
_HTTPClient?.AddSocketObjectHandler(SocketObject_Handler);
SendingHeartBeatTask = Task.Factory.StartNew(SendHeartBeat);
}
}
public void StopSendingHeartBeat()
{
_SendingHeartBeat = false;
SendingHeartBeatTask?.Wait(1);
SendingHeartBeatTask = null;
_Socket?.RemoveSocketObjectHandler(SocketObject_Handler);
_HTTPClient?.RemoveSocketObjectHandler(SocketObject_Handler);
}
private async Task SendHeartBeat()
{
await Task.Delay(100);
if (_Socket != null)
{
while (_Socket.Connected)
{
if (!SendingHeartBeat) _SendingHeartBeat = true;
// 发送心跳包
_LastHeartbeatReceived = false;
if (_Socket.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
{
await Task.Delay(4 * 1000);
if (!_LastHeartbeatReceived) AddHeartBeatFaileds();
}
else AddHeartBeatFaileds();
await Task.Delay(20 * 1000);
}
}
else if (_HTTPClient != null)
{
while (_HTTPClient.Instance?.State == System.Net.WebSockets.WebSocketState.Open)
{
if (!SendingHeartBeat) _SendingHeartBeat = true;
// 发送心跳包
if (await _HTTPClient.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
{
await Task.Delay(4 * 1000);
AddHeartBeatFaileds();
}
else AddHeartBeatFaileds();
await Task.Delay(20 * 1000);
}
}
_SendingHeartBeat = false;
}
private void AddHeartBeatFaileds()
{
// 超过三次没回应心跳,服务器连接失败。
if (_HeartBeatFaileds++ >= 3)
{
_Socket?.Close();
_HTTPClient?.Close();
throw new LostConnectException();
}
}
private void SocketObject_Handler(SocketObject obj)
{
if (obj.SocketType == SocketMessageType.HeartBeat)
{
_LastHeartbeatReceived = true;
_HeartBeatFaileds = 0;
}
}
}
}