mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-04-22 12:09:34 +08:00

* 完善 HTTPClient;添加日志级别;添加匿名服务器模组(此模组不强制要求登录、客户端安装) * 添加参数 * 添加 null 检查 * 修复不同时间多客户端连接游戏模组时可能产生的线程安全问题
127 lines
4.3 KiB
C#
127 lines
4.3 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()
|
|
{
|
|
try
|
|
{
|
|
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.WebSocket?.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;
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
if (_Socket != null)
|
|
{
|
|
_Socket.OnConnectionLost(e);
|
|
_Socket.Close();
|
|
}
|
|
if (_HTTPClient != null)
|
|
{
|
|
_HTTPClient.OnConnectionLost(e);
|
|
_HTTPClient.Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|