mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2025-04-22 03:59:35 +08:00

* 重做 WebSocket 监听;为服务器统一了多种数据连接访问时的处理;统一编码为 UTF-8 * ModelManager已更名并移动到工具命名空间中 * 完成 WebSocket 消息处理系统 * 添加Socket异步接收数据流;修复TaskUtility阻塞的问题;优化心跳、房间、模组 * 添加枚举 * 删除多余字符 * 添加监听器的名称 * 修改了命名
114 lines
4.3 KiB
C#
114 lines
4.3 KiB
C#
using System.Net.WebSockets;
|
|
using Milimoe.FunGame.Core.Interface.HTTP;
|
|
using Milimoe.FunGame.Core.Library.Common.Architecture;
|
|
using Milimoe.FunGame.Core.Library.Constant;
|
|
using Milimoe.FunGame.Core.Library.Exception;
|
|
using Milimoe.FunGame.Core.Service;
|
|
|
|
namespace Milimoe.FunGame.Core.Library.Common.Network
|
|
{
|
|
public class HTTPClient : IHTTPClient
|
|
{
|
|
public System.Net.WebSockets.ClientWebSocket? Instance { get; } = null;
|
|
public SocketRuntimeType Runtime => SocketRuntimeType.Client;
|
|
public Guid Token { get; set; } = Guid.Empty;
|
|
public string ServerAddress { get; } = "";
|
|
public int ServerPort { get; } = 0;
|
|
public string ServerName { get; } = "";
|
|
public string ServerNotice { get; } = "";
|
|
public bool Connected => Instance != null && Instance.State == WebSocketState.Open;
|
|
public bool Receiving => _receiving;
|
|
private HeartBeat HeartBeat { get; }
|
|
|
|
private bool _receiving = false;
|
|
private readonly HashSet<Action<SocketObject>> _boundEvents = [];
|
|
|
|
private HTTPClient(System.Net.WebSockets.ClientWebSocket instance, string serverAddress, int serverPort, params object[] args)
|
|
{
|
|
Instance = instance;
|
|
ServerAddress = serverAddress;
|
|
ServerPort = serverPort;
|
|
HeartBeat = new(this);
|
|
HeartBeat.StartSendingHeartBeat();
|
|
Task.Factory.StartNew(async () => await StartListening(args));
|
|
}
|
|
|
|
public static async Task<HTTPClient> Connect(string serverAddress, int serverPort, bool ssl, string subUrl = "", params object[] args)
|
|
{
|
|
string ServerIP = Api.Utility.NetworkUtility.GetIPAddress(serverAddress);
|
|
Uri uri = new((ssl ? "wss://" : "ws://") + ServerIP + ":" + serverPort + "/" + subUrl.Trim('/') + "/");
|
|
System.Net.WebSockets.ClientWebSocket? socket = await HTTPManager.Connect(uri);
|
|
if (socket != null && socket.State == WebSocketState.Open)
|
|
{
|
|
HTTPClient client = new(socket, serverAddress, serverPort, args);
|
|
return client;
|
|
}
|
|
throw new CanNotConnectException();
|
|
}
|
|
|
|
public async Task Receive()
|
|
{
|
|
while (_receiving)
|
|
{
|
|
try
|
|
{
|
|
await HTTPManager.ReceiveMessage(this);
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Close();
|
|
Api.Utility.TXTHelper.AppendErrorLog(e.GetErrorInfo());
|
|
throw new SocketWrongInfoException();
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<SocketResult> Send(SocketMessageType type, params object[] objs)
|
|
{
|
|
if (Instance != null)
|
|
{
|
|
return await HTTPManager.Send(Instance, new(type, Token, objs));
|
|
}
|
|
return SocketResult.NotSent;
|
|
}
|
|
|
|
public void AddSocketObjectHandler(Action<SocketObject> method)
|
|
{
|
|
if (_boundEvents.Add(method))
|
|
{
|
|
SocketManager.SocketReceive += new SocketManager.SocketReceiveHandler(method);
|
|
}
|
|
}
|
|
|
|
public void RemoveSocketObjectHandler(Action<SocketObject> method)
|
|
{
|
|
_boundEvents.Remove(method);
|
|
SocketManager.SocketReceive -= new SocketManager.SocketReceiveHandler(method);
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
_receiving = false;
|
|
HeartBeat.StopSendingHeartBeat();
|
|
Instance?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
|
Instance?.Dispose();
|
|
foreach (Action<SocketObject> method in _boundEvents.ToList())
|
|
{
|
|
RemoveSocketObjectHandler(method);
|
|
}
|
|
}
|
|
|
|
private async Task StartListening(params object[] args)
|
|
{
|
|
if (Instance != null && Instance.State == WebSocketState.Open)
|
|
{
|
|
if (await HTTPManager.Send(Instance, new(SocketMessageType.Connect, Guid.Empty, args)) == SocketResult.Success && await HTTPManager.ReceiveMessage(this))
|
|
{
|
|
_receiving = true;
|
|
await Receive();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|