mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2026-04-20 05:24:59 +00:00
网络层优化 (#152)
This commit is contained in:
parent
ce29844593
commit
a6087f98a6
@ -27,10 +27,14 @@ namespace Milimoe.FunGame.Core.Api.Transmittal
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisposed => _isDisposed;
|
public bool IsDisposed => _isDisposed;
|
||||||
|
|
||||||
// 获取ResultData中key值对应的Json字符串
|
/// <summary>
|
||||||
// -- 此索引器仅返回Json字符串,对象类型请使用反序列化方法GetResult<T>() --
|
/// 获取ResultData中key值对应的Json字符串
|
||||||
// -- 当然也可以自己反序列化 --
|
/// <para/>-- 此索引器仅返回Json字符串,对象类型请使用反序列化方法GetResult{T}() --
|
||||||
// -- 基本类型可能有效,但仍建议使用反序列化方法 --
|
/// <para/>-- 当然也可以自己反序列化 --
|
||||||
|
/// <para/>-- 基本类型可能有效,但仍建议使用反序列化方法 --
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public object? this[string key]
|
public object? this[string key]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@ -21,14 +21,14 @@ namespace Milimoe.FunGame.Core.Api.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TaskScheduler()
|
public TaskScheduler()
|
||||||
{
|
{
|
||||||
Task.Factory.StartNew(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
CheckAndRunTasks();
|
CheckAndRunTasks();
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
}
|
}
|
||||||
}, TaskCreationOptions.LongRunning);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -520,7 +520,7 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected void StartReceiving()
|
protected void StartReceiving()
|
||||||
{
|
{
|
||||||
_ReceivingTask = Task.Factory.StartNew(() =>
|
_ReceivingTask = Task.Run(() =>
|
||||||
{
|
{
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
_IsReceiving = true;
|
_IsReceiving = true;
|
||||||
|
|||||||
@ -1,20 +1,25 @@
|
|||||||
using Milimoe.FunGame.Core.Interface.Sockets;
|
using System.Diagnostics;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Sockets;
|
||||||
using Milimoe.FunGame.Core.Library.Common.Network;
|
using Milimoe.FunGame.Core.Library.Common.Network;
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
||||||
{
|
{
|
||||||
public class HeartBeat : ISocketHeartBeat
|
internal class HeartBeat : ISocketHeartBeat
|
||||||
{
|
{
|
||||||
public TransmittalType TransmittalType { get; } = TransmittalType.Socket;
|
public TransmittalType TransmittalType { get; } = TransmittalType.Socket;
|
||||||
public bool SendingHeartBeat => _sendingHeartBeat;
|
public bool SendingHeartBeat => _sendingHeartBeat;
|
||||||
public int HeartBeatFaileds => _heartBeatFaileds;
|
public int HeartBeatFaileds => _heartBeatFaileds;
|
||||||
|
public int Ping => Math.Min(_ping, 999);
|
||||||
|
|
||||||
private Task? _sendingHeartBeatTask;
|
private Task? _sendingHeartBeatTask;
|
||||||
private bool _sendingHeartBeat = false;
|
private bool _sendingHeartBeat = false;
|
||||||
private bool _lastHeartbeatReceived = false;
|
|
||||||
private int _heartBeatFaileds = 0;
|
private int _heartBeatFaileds = 0;
|
||||||
|
private string _currentProbeId = "";
|
||||||
|
private long _lastSentTimestamp;
|
||||||
|
private int _ping = 0;
|
||||||
|
|
||||||
|
private readonly Lock _probeLock = new();
|
||||||
private readonly Socket? _socket = null;
|
private readonly Socket? _socket = null;
|
||||||
private readonly HTTPClient? _httpClient = null;
|
private readonly HTTPClient? _httpClient = null;
|
||||||
|
|
||||||
@ -37,7 +42,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
_sendingHeartBeat = true;
|
_sendingHeartBeat = true;
|
||||||
_socket?.AddSocketObjectHandler(SocketObject_Handler);
|
_socket?.AddSocketObjectHandler(SocketObject_Handler);
|
||||||
_httpClient?.AddSocketObjectHandler(SocketObject_Handler);
|
_httpClient?.AddSocketObjectHandler(SocketObject_Handler);
|
||||||
_sendingHeartBeatTask = Task.Factory.StartNew(SendHeartBeat);
|
_sendingHeartBeatTask = Task.Run(SendHeartBeat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,39 +60,45 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
if (_socket != null)
|
while (_sendingHeartBeat)
|
||||||
{
|
{
|
||||||
while (_socket.Connected)
|
// 发送心跳包
|
||||||
|
string probeId = Guid.NewGuid().ToString();
|
||||||
|
lock (_probeLock)
|
||||||
{
|
{
|
||||||
if (!SendingHeartBeat) _sendingHeartBeat = true;
|
_currentProbeId = probeId;
|
||||||
// 发送心跳包
|
_lastSentTimestamp = Stopwatch.GetTimestamp();
|
||||||
_lastHeartbeatReceived = false;
|
}
|
||||||
if (_socket.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
try
|
||||||
|
{
|
||||||
|
bool sendSuccess = false;
|
||||||
|
if (_socket != null)
|
||||||
|
{
|
||||||
|
sendSuccess = _socket.Connected && _socket.Send(SocketMessageType.HeartBeat, _currentProbeId) == SocketResult.Success;
|
||||||
|
}
|
||||||
|
else if (_httpClient != null)
|
||||||
|
{
|
||||||
|
sendSuccess = _httpClient.WebSocket?.State == System.Net.WebSockets.WebSocketState.Open && await _httpClient.Send(SocketMessageType.HeartBeat, _currentProbeId) == SocketResult.Success;
|
||||||
|
}
|
||||||
|
if (!sendSuccess)
|
||||||
|
{
|
||||||
|
throw new ConnectFailedException();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
await Task.Delay(4 * 1000);
|
await Task.Delay(4 * 1000);
|
||||||
if (!_lastHeartbeatReceived) AddHeartBeatFaileds();
|
lock (_probeLock)
|
||||||
|
{
|
||||||
|
if (_currentProbeId == probeId) throw new TimeOutException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else AddHeartBeatFaileds();
|
|
||||||
await Task.Delay(20 * 1000);
|
|
||||||
}
|
}
|
||||||
}
|
catch
|
||||||
else if (_httpClient != null)
|
|
||||||
{
|
|
||||||
while (_httpClient.WebSocket?.State == System.Net.WebSockets.WebSocketState.Open)
|
|
||||||
{
|
{
|
||||||
if (!SendingHeartBeat) _sendingHeartBeat = true;
|
AddHeartBeatFaileds();
|
||||||
// 发送心跳包
|
|
||||||
_lastHeartbeatReceived = false;
|
|
||||||
if (await _httpClient.Send(SocketMessageType.HeartBeat) == SocketResult.Success)
|
|
||||||
{
|
|
||||||
await Task.Delay(4 * 1000);
|
|
||||||
if (!_lastHeartbeatReceived) AddHeartBeatFaileds();
|
|
||||||
}
|
|
||||||
else AddHeartBeatFaileds();
|
|
||||||
await Task.Delay(20 * 1000);
|
|
||||||
}
|
}
|
||||||
|
await Task.Delay(20 * 1000);
|
||||||
}
|
}
|
||||||
_sendingHeartBeat = false;
|
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
@ -102,12 +113,18 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
_httpClient.Close();
|
_httpClient.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_sendingHeartBeat = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddHeartBeatFaileds()
|
private void AddHeartBeatFaileds()
|
||||||
{
|
{
|
||||||
|
_currentProbeId = "";
|
||||||
|
_ping = 999;
|
||||||
// 超过三次没回应心跳,服务器连接失败。
|
// 超过三次没回应心跳,服务器连接失败。
|
||||||
if (_heartBeatFaileds++ >= 3)
|
if (++_heartBeatFaileds >= 3)
|
||||||
{
|
{
|
||||||
_socket?.Close();
|
_socket?.Close();
|
||||||
_httpClient?.Close();
|
_httpClient?.Close();
|
||||||
@ -119,8 +136,22 @@ namespace Milimoe.FunGame.Core.Library.Common.Architecture
|
|||||||
{
|
{
|
||||||
if (obj.SocketType == SocketMessageType.HeartBeat)
|
if (obj.SocketType == SocketMessageType.HeartBeat)
|
||||||
{
|
{
|
||||||
_lastHeartbeatReceived = true;
|
string receivedId = "";
|
||||||
_heartBeatFaileds = 0;
|
if (obj.Length > 0)
|
||||||
|
{
|
||||||
|
receivedId = obj.GetParam<string>(0) ?? "";
|
||||||
|
}
|
||||||
|
lock (_probeLock)
|
||||||
|
{
|
||||||
|
if (receivedId == _currentProbeId && !string.IsNullOrEmpty(_currentProbeId))
|
||||||
|
{
|
||||||
|
long elapsedTicks = Stopwatch.GetTimestamp() - _lastSentTimestamp;
|
||||||
|
double rttMs = elapsedTicks * 1000.0 / Stopwatch.Frequency;
|
||||||
|
_ping = (int)Math.Round(rttMs);
|
||||||
|
_heartBeatFaileds = 0;
|
||||||
|
_currentProbeId = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
public string ServerNotice { get; } = "";
|
public string ServerNotice { get; } = "";
|
||||||
public bool Connected => WebSocket != null && WebSocket.State == WebSocketState.Open;
|
public bool Connected => WebSocket != null && WebSocket.State == WebSocketState.Open;
|
||||||
public bool Receiving => _receiving;
|
public bool Receiving => _receiving;
|
||||||
|
public int Ping => HeartBeat.Ping;
|
||||||
private HeartBeat HeartBeat { get; }
|
private HeartBeat HeartBeat { get; }
|
||||||
|
|
||||||
public event Action<System.Exception>? ConnectionLost;
|
public event Action<System.Exception>? ConnectionLost;
|
||||||
@ -36,7 +37,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
ServerPort = serverPort;
|
ServerPort = serverPort;
|
||||||
HeartBeat = new(this);
|
HeartBeat = new(this);
|
||||||
HeartBeat.StartSendingHeartBeat();
|
HeartBeat.StartSendingHeartBeat();
|
||||||
Task.Factory.StartNew(async () => await StartListening(args));
|
Task.Run(async () => await StartListening(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<HTTPClient> Connect(string serverAddress, bool ssl, int serverPort = 0, string subUrl = "", params object[] args)
|
public static async Task<HTTPClient> Connect(string serverAddress, bool ssl, int serverPort = 0, string subUrl = "", params object[] args)
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
public string ServerNotice { get; } = "";
|
public string ServerNotice { get; } = "";
|
||||||
public bool Connected => Instance != null && Instance.Connected;
|
public bool Connected => Instance != null && Instance.Connected;
|
||||||
public bool Receiving => _receiving;
|
public bool Receiving => _receiving;
|
||||||
|
public int Ping => HeartBeat.Ping;
|
||||||
private HeartBeat HeartBeat { get; }
|
private HeartBeat HeartBeat { get; }
|
||||||
|
|
||||||
public event Action<System.Exception>? ConnectionLost;
|
public event Action<System.Exception>? ConnectionLost;
|
||||||
@ -28,9 +29,9 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
|
|||||||
|
|
||||||
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;
|
Instance = instance;
|
||||||
this.ServerAddress = serverAddress;
|
ServerAddress = serverAddress;
|
||||||
this.ServerPort = serverPort;
|
ServerPort = serverPort;
|
||||||
HeartBeat = new(this);
|
HeartBeat = new(this);
|
||||||
HeartBeat.StartSendingHeartBeat();
|
HeartBeat.StartSendingHeartBeat();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user