使用 HeartBeat 对象处理心跳 (#78)

This commit is contained in:
milimoe 2024-07-31 11:20:14 +08:00 committed by GitHub
parent 30d10d6e22
commit e944b0232c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 7 additions and 73 deletions

View File

@ -10,7 +10,6 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public class HTTPClient : IHTTPClient public class HTTPClient : IHTTPClient
{ {
public ClientWebSocket? Instance { get; } = null; public ClientWebSocket? Instance { get; } = null;
public HeartBeat HeartBeat { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Client; public SocketRuntimeType Runtime => SocketRuntimeType.Client;
public Guid Token { get; } = Guid.Empty; public Guid Token { get; } = Guid.Empty;
public string ServerAddress { get; } = ""; public string ServerAddress { get; } = "";
@ -19,6 +18,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public string ServerNotice { get; } = ""; public string ServerNotice { get; } = "";
private bool _Listening = false; private bool _Listening = false;
private readonly HeartBeat HeartBeat;
private HTTPClient(ClientWebSocket Instance, string ServerAddress, int ServerPort, params object[] args) private HTTPClient(ClientWebSocket Instance, string ServerAddress, int ServerPort, params object[] args)
{ {

View File

@ -1,11 +1,12 @@
using Milimoe.FunGame.Core.Interface.Sockets; using Milimoe.FunGame.Core.Interface.Sockets;
using Milimoe.FunGame.Core.Library.Common.Architecture;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Library.Exception; using Milimoe.FunGame.Core.Library.Exception;
using Milimoe.FunGame.Core.Service; using Milimoe.FunGame.Core.Service;
namespace Milimoe.FunGame.Core.Library.Common.Network namespace Milimoe.FunGame.Core.Library.Common.Network
{ {
public class Socket : IClientSocket, ISocketHeartBeat public class Socket : IClientSocket
{ {
public System.Net.Sockets.Socket Instance { get; } public System.Net.Sockets.Socket Instance { get; }
public SocketRuntimeType Runtime => SocketRuntimeType.Client; public SocketRuntimeType Runtime => SocketRuntimeType.Client;
@ -14,25 +15,20 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public int ServerPort { get; } = 0; public int ServerPort { get; } = 0;
public string ServerName { get; } = ""; public string ServerName { get; } = "";
public string ServerNotice { get; } = ""; public string ServerNotice { get; } = "";
public int HeartBeatFaileds => _HeartBeatFaileds;
public bool Connected => Instance != null && Instance.Connected; public bool Connected => Instance != null && Instance.Connected;
public bool Receiving => _Receiving; public bool Receiving => _Receiving;
public bool SendingHeartBeat => _SendingHeartBeat;
private Task? SendingHeartBeatTask;
private Task? ReceivingTask; private Task? ReceivingTask;
private Task? WaitHeartBeatReply; private readonly HeartBeat HeartBeat;
private bool _Receiving = false; private bool _Receiving = false;
private bool _SendingHeartBeat = false;
private int _HeartBeatFaileds = 0;
private Socket(System.Net.Sockets.Socket Instance, string ServerAddress, int ServerPort) private Socket(System.Net.Sockets.Socket Instance, string ServerAddress, int ServerPort)
{ {
this.Instance = Instance; this.Instance = Instance;
this.ServerAddress = ServerAddress; this.ServerAddress = ServerAddress;
this.ServerPort = ServerPort; this.ServerPort = ServerPort;
this.StartSendingHeartBeat(); HeartBeat = new(this);
HeartBeat.StartSendingHeartBeat();
} }
public static Socket Connect(string Address, int Port = 22222) public static Socket Connect(string Address, int Port = 22222)
@ -60,14 +56,6 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
try try
{ {
SocketObject[] result = SocketManager.Receive(); SocketObject[] result = SocketManager.Receive();
foreach (SocketObject obj in result)
{
if (obj.SocketType == SocketMessageType.HeartBeat)
{
if (WaitHeartBeatReply != null && !WaitHeartBeatReply.IsCompleted) WaitHeartBeatReply.Wait(1);
_HeartBeatFaileds = 0;
}
}
return result; return result;
} }
catch (System.Exception e) catch (System.Exception e)
@ -89,78 +77,24 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
} }
} }
public void CheckHeartBeatFaileds()
{
if (HeartBeatFaileds >= 3) Close();
}
public void Close() public void Close()
{ {
StopSendingHeartBeat(); HeartBeat.StopSendingHeartBeat();
StopReceiving(); StopReceiving();
Instance?.Close(); Instance?.Close();
} }
public void ResetHeartBeatFaileds()
{
_HeartBeatFaileds = 0;
}
public void StartReceiving(Task t) public void StartReceiving(Task t)
{ {
_Receiving = true; _Receiving = true;
ReceivingTask = t; ReceivingTask = t;
} }
private void StartSendingHeartBeat()
{
if (!FunGameInfo.FunGame_DebugMode)
{
_SendingHeartBeat = true;
SendingHeartBeatTask = Task.Factory.StartNew(SendHeartBeat);
}
}
private void StopReceiving() private void StopReceiving()
{ {
_Receiving = false; _Receiving = false;
ReceivingTask?.Wait(1); ReceivingTask?.Wait(1);
ReceivingTask = null; ReceivingTask = null;
} }
private void StopSendingHeartBeat()
{
_SendingHeartBeat = false;
SendingHeartBeatTask?.Wait(1);
SendingHeartBeatTask = null;
}
private void SendHeartBeat()
{
Thread.Sleep(100);
while (Connected)
{
if (!SendingHeartBeat) _SendingHeartBeat = true;
// 发送心跳包
if (Send(SocketMessageType.HeartBeat) == SocketResult.Success)
{
WaitHeartBeatReply = Task.Run(() =>
{
Thread.Sleep(4000);
AddHeartBeatFaileds();
});
}
else AddHeartBeatFaileds();
Thread.Sleep(20000);
}
_SendingHeartBeat = false;
}
private void AddHeartBeatFaileds()
{
// 超过三次没回应心跳,服务器连接失败。
if (_HeartBeatFaileds++ >= 3)
throw new LostConnectException();
}
} }
} }