diff --git a/Api/Transmittal/DataRequest.cs b/Api/Transmittal/DataRequest.cs index 5fb7a38..b392be1 100644 --- a/Api/Transmittal/DataRequest.cs +++ b/Api/Transmittal/DataRequest.cs @@ -1,8 +1,8 @@ using System.Collections; +using Milimoe.FunGame.Core.Controller; using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Exception; -using Milimoe.FunGame.Core.Model; namespace Milimoe.FunGame.Core.Api.Transmittal { @@ -100,7 +100,7 @@ namespace Milimoe.FunGame.Core.Api.Transmittal return GetHashtableJsonObject(Worker.ResultData, key); } - private class Request : SocketHandlerModel + private class Request : SocketHandlerController { public Hashtable RequestData { get; } = new(); public Hashtable ResultData => _ResultData; diff --git a/Controller/RunTimeController.cs b/Controller/RunTimeController.cs index 6c5e4cc..1d9ecb2 100644 --- a/Controller/RunTimeController.cs +++ b/Controller/RunTimeController.cs @@ -1,24 +1,247 @@ using Milimoe.FunGame.Core.Api.Transmittal; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Network; using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; namespace Milimoe.FunGame.Core.Controller { + /// + /// 此类实现服务器连接、断开连接、心跳检测、创建数据请求等功能 + /// -- 需要继承并实现部分方法 -- + /// public abstract class RunTimeController { - public abstract bool Connected { get; } + /// + /// 与服务器的连接套接字实例 + /// + public Socket? Socket => _Socket; - public abstract Task Connect(); + /// + /// 套接字是否已经连接 + /// + public bool Connected => _Socket != null && _Socket.Connected; - public abstract bool Disconnect(); + /// + /// 接收服务器信息的线程 + /// + protected Task? _ReceivingTask; - public abstract bool Close(Exception? e = null); + /// + /// 用于类内赋值 + /// + protected Socket? _Socket; - public abstract bool Error(Exception e); + /// + /// 是否正在接收服务器信息 + /// + protected bool _IsReceiving; - public abstract Task AutoLogin(string Username, string Password, string AutoKey); + /// + /// 断开服务器连接 + /// + /// + public bool Disconnect() + { + bool result = false; + try + { + result = _Socket?.Send(SocketMessageType.RunTime_Disconnect, "") == SocketResult.Success; + } + catch (Exception e) + { + WritelnSystemInfo(e.GetErrorInfo()); + } + + return result; + } + + /// + /// 获取服务器地址 + /// + /// string:IP地址;int:端口号 + /// + public (string, int) GetServerAddress() + { + try + { + string? ipaddress = (string?)Implement.GetFunGameImplValue(InterfaceType.IClient, InterfaceMethod.RemoteServerIP); + if (ipaddress != null) + { + string[] s = ipaddress.Split(':'); + if (s != null && s.Length > 1) + { + return (s[0], Convert.ToInt32(s[1])); + } + } + throw new FindServerFailedException(); + } + catch (FindServerFailedException e) + { + WritelnSystemInfo(e.GetErrorInfo()); + return ("", 0); + } + } + + /// + /// 客户端需要自行实现连接服务器的事务 + /// + /// 连接结果 + public abstract ConnectResult Connect(); + + /// + /// 关闭所有连接 + /// + /// + public bool Close() + { + try + { + if (_Socket != null) + { + _Socket.Close(); + _Socket = null; + } + if (_ReceivingTask != null && !_ReceivingTask.IsCompleted) + { + _ReceivingTask.Wait(1); + _ReceivingTask = null; + _IsReceiving = false; + } + } + catch (Exception e) + { + WritelnSystemInfo(e.GetErrorInfo()); + return false; + } + return true; + } + + /// + /// 输出消息 + /// + /// public abstract void WritelnSystemInfo(string msg); - public abstract DataRequest NewDataRequest(DataRequestType RequestType); + /// + /// 自定处理异常的方法 + /// -- 一般放在catch中 -- + /// + /// + public abstract void Error(Exception e); + + /// + /// 基于本地已连接的Socket创建新的数据请求 + /// + /// + /// + /// + public DataRequest NewDataRequest(DataRequestType RequestType) + { + if (_Socket != null) + { + DataRequest request = new(_Socket, RequestType); + return request; + } + throw new ConnectFailedException(); + } + + /// + /// 开始接收服务器信息 + /// + protected void StartReceiving() + { + _ReceivingTask = Task.Factory.StartNew(() => + { + Thread.Sleep(100); + _IsReceiving = true; + while (Connected) + { + Receiving(); + } + }); + _Socket?.StartReceiving(_ReceivingTask); + } + + /// + /// 获取服务器已发送的信息为SocketObject数组 + /// + /// + protected SocketObject[] GetServerMessage() + { + if (_Socket != null && _Socket.Connected) + { + return _Socket.ReceiveArray(); + } + return Array.Empty(); + } + + /// + /// 具体接收服务器信息以及处理信息的方法 + /// + /// + protected SocketMessageType Receiving() + { + if (_Socket is null) return SocketMessageType.Unknown; + SocketMessageType result = SocketMessageType.Unknown; + try + { + SocketObject[] ServerMessages = GetServerMessage(); + + foreach (SocketObject ServerMessage in ServerMessages) + { + SocketMessageType type = ServerMessage.SocketType; + object[] objs = ServerMessage.Parameters; + result = type; + switch (type) + { + case SocketMessageType.RunTime_Connect: + if (!SocketHandler_Connect(ServerMessage)) return SocketMessageType.Unknown; + break; + + case SocketMessageType.RunTime_Disconnect: + SocketHandler_Disconnect(ServerMessage); + break; + + case SocketMessageType.RunTime_HeartBeat: + if (_Socket != null && _Socket.Connected) + { + SocketHandler_HeartBeat(ServerMessage); + } + break; + + case SocketMessageType.Unknown: + default: + break; + } + } + } + catch (Exception e) + { + // 报错中断服务器连接 + Error(e); + } + return result; + } + + /// + /// 连接服务器的处理方法 + /// + /// + /// + protected abstract bool SocketHandler_Connect(SocketObject ServerMessage); + + /// + /// 与服务器断开连接的处理方法 + /// + /// + protected abstract void SocketHandler_Disconnect(SocketObject ServerMessage); + + /// + /// 心跳检测处理方法 + /// + /// + protected abstract void SocketHandler_HeartBeat(SocketObject ServerMessage); } } diff --git a/Controller/SocketHandlerController.cs b/Controller/SocketHandlerController.cs index fb2c8aa..ff3d26d 100644 --- a/Controller/SocketHandlerController.cs +++ b/Controller/SocketHandlerController.cs @@ -1,10 +1,79 @@ -namespace Milimoe.FunGame.Core.Controller +using Milimoe.FunGame.Core.Interface.Base; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Service; + +namespace Milimoe.FunGame.Core.Controller { - public abstract class SocketHandlerController + /// + /// 继承 AsyncAwaiter 用法: + /// 1、调用Socket.Send()前,请设置为等待状态:SetWorking(); + /// 2、调用Socket.Send() == Success后,请等待任务完成:WaitForWorkDone(); + /// 3、在其他任何地方修改Working状态,均会使任务终止。 + /// + public class SocketHandlerController : AsyncAwaiter, ISocketHandler, IDisposable { /// - /// 重写此方法并调用Model的Dispose方法,否则将无法正常将监听Socket的事件移除! + /// 接收到的SocketObject实例 /// - public abstract void Dispose(); + protected override SocketObject Work { get; set; } + + /// + /// Socket + /// + private readonly Socket _Socket; + + /// + /// 继承请调用base构造 + /// + /// Socket + public SocketHandlerController(Socket? socket) + { + if (socket != null) + { + _Socket = socket; + socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler)); + } + else throw new SocketCreateReceivingException(); + } + + /// + /// 继承请重写此方法 + /// + /// SocketObject + public virtual void SocketHandler(SocketObject SocketObject) + { + + } + + /// + /// 判断是否已经Disposed + /// + private bool IsDisposed = false; + + /// + /// 公开的Dispose方法 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 关闭时 + /// + /// + protected void Dispose(bool Disposing) + { + if (!IsDisposed) + { + if (Disposing) + { + _Socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler), true); + } + } + IsDisposed = true; + } } } \ No newline at end of file diff --git a/Library/Common/Event/ConnectEventArgs.cs b/Library/Common/Event/ConnectEventArgs.cs index c1ae7d2..60cf2d9 100644 --- a/Library/Common/Event/ConnectEventArgs.cs +++ b/Library/Common/Event/ConnectEventArgs.cs @@ -1,17 +1,18 @@ -namespace Milimoe.FunGame.Core.Library.Common.Event +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Core.Library.Common.Event { public class ConnectEventArgs : GeneralEventArgs { public string ServerIP { get; set; } = "127.0.0.1"; public int ServerPort { get; set; } = 22222; + public ConnectResult ConnectResult { get; set; } = ConnectResult.Success; - public ConnectEventArgs(params object[]? objs) + public ConnectEventArgs(string ip = "", int port = 0, ConnectResult result = ConnectResult.Success) { - if (objs != null) - { - if (objs.Length > 0) ServerIP = (string)objs[0]; - if (objs.Length > 1) ServerPort = (int)objs[1]; - } + if (ip.Trim() != "") ServerIP = ip; + if (port != 0) ServerPort = port; + ConnectResult = result; } } } diff --git a/Library/Common/Event/LoginEventArgs.cs b/Library/Common/Event/LoginEventArgs.cs index f903dcc..12724cb 100644 --- a/Library/Common/Event/LoginEventArgs.cs +++ b/Library/Common/Event/LoginEventArgs.cs @@ -6,14 +6,11 @@ public string Password { get; set; } = ""; public string AutoKey { get; set; } = ""; - public LoginEventArgs(params object[]? objs) + public LoginEventArgs(string username = "", string password = "", string autokey = "") { - if (objs != null) - { - if (objs.Length > 0) Username = (string)objs[0]; - if (objs.Length > 1) Password = (string)objs[1]; - if (objs.Length > 2) AutoKey = (string)objs[2]; - } + if (username.Trim() != "") Username = username; + if (password.Trim() != "") Password = password; + if (autokey.Trim() != "") AutoKey = autokey; } } } diff --git a/Library/Common/Event/RegisterEventArgs.cs b/Library/Common/Event/RegisterEventArgs.cs index 35ebe95..df7d70c 100644 --- a/Library/Common/Event/RegisterEventArgs.cs +++ b/Library/Common/Event/RegisterEventArgs.cs @@ -6,14 +6,11 @@ public string Password { get; set; } = ""; public string Email { get; set; } = ""; - public RegisterEventArgs(params object[]? objs) + public RegisterEventArgs(string username = "", string password = "", string email = "") { - if (objs != null) - { - if (objs.Length > 0) Username = (string)objs[0]; - if (objs.Length > 1) Password = (string)objs[1]; - if (objs.Length > 2) Email = (string)objs[2]; - } + if (username.Trim() != "") Username = username; + if (password.Trim() != "") Password = password; + if (email.Trim() != "") Email = email; } } } diff --git a/Model/RunTime.cs b/Model/RunTime.cs deleted file mode 100644 index b18c988..0000000 --- a/Model/RunTime.cs +++ /dev/null @@ -1,247 +0,0 @@ -using Milimoe.FunGame.Core.Api.Transmittal; -using Milimoe.FunGame.Core.Api.Utility; -using Milimoe.FunGame.Core.Controller; -using Milimoe.FunGame.Core.Library.Common.Network; -using Milimoe.FunGame.Core.Library.Constant; -using Milimoe.FunGame.Core.Library.Exception; - -namespace Milimoe.FunGame.Core.Model -{ - /// - /// 此类实现服务器连接、断开连接、心跳检测、创建数据请求等功能 - /// -- 需要继承并实现部分方法 -- - /// - public abstract class RunTime - { - /// - /// 与服务器的连接套接字实例 - /// - public Socket? Socket => _Socket; - - /// - /// 套接字是否已经连接 - /// - public bool Connected => _Socket != null && _Socket.Connected; - - /// - /// 接收服务器信息的线程 - /// - protected Task? _ReceivingTask; - - /// - /// 用于类内赋值 - /// - protected Socket? _Socket; - - /// - /// 是否正在接收服务器信息 - /// - protected bool _IsReceiving; - - /// - /// 是否拥有一个控制器 - /// - protected RunTimeController? _Controller; - - /// - /// 断开服务器连接 - /// - /// - public bool Disconnect() - { - bool result = false; - - try - { - result = _Socket?.Send(SocketMessageType.RunTime_Disconnect, "") == SocketResult.Success; - } - catch (Exception e) - { - _Controller?.WritelnSystemInfo(e.GetErrorInfo()); - } - - return result; - } - - /// - /// 获取服务器地址 - /// - /// string:IP地址;int:端口号 - /// - public (string, int) GetServerAddress() - { - try - { - string? ipaddress = (string?)Implement.GetFunGameImplValue(InterfaceType.IClient, InterfaceMethod.RemoteServerIP); - if (ipaddress != null) - { - string[] s = ipaddress.Split(':'); - if (s != null && s.Length > 1) - { - return (s[0], Convert.ToInt32(s[1])); - } - } - throw new FindServerFailedException(); - } - catch (FindServerFailedException e) - { - _Controller?.WritelnSystemInfo(e.GetErrorInfo()); - return ("", 0); - } - } - - /// - /// 客户端需要自行实现连接服务器的事务 - /// - /// 支持异步 - public abstract Task Connect(); - - /// - /// 关闭所有连接 - /// - /// - public bool Close() - { - try - { - if (_Socket != null) - { - _Socket.Close(); - _Socket = null; - } - if (_ReceivingTask != null && !_ReceivingTask.IsCompleted) - { - _ReceivingTask.Wait(1); - _ReceivingTask = null; - _IsReceiving = false; - } - } - catch (Exception e) - { - _Controller?.WritelnSystemInfo(e.GetErrorInfo()); - return false; - } - return true; - } - - /// - /// 自定处理异常的方法 - /// -- 一般放在catch中 -- - /// - /// - public abstract void Error(Exception e); - - /// - /// 基于本地已连接的Socket创建新的数据请求 - /// - /// - /// - /// - public DataRequest NewDataRequest(DataRequestType RequestType) - { - if (_Socket != null) - { - DataRequest request = new(_Socket, RequestType); - return request; - } - throw new ConnectFailedException(); - } - - /// - /// 开始接收服务器信息 - /// - protected void StartReceiving() - { - _ReceivingTask = Task.Factory.StartNew(() => - { - Thread.Sleep(100); - _IsReceiving = true; - while (Connected) - { - Receiving(); - } - }); - _Socket?.StartReceiving(_ReceivingTask); - } - - /// - /// 获取服务器已发送的信息为SocketObject数组 - /// - /// - protected SocketObject[] GetServerMessage() - { - if (_Socket != null && _Socket.Connected) - { - return _Socket.ReceiveArray(); - } - return Array.Empty(); - } - - /// - /// 具体接收服务器信息以及处理信息的方法 - /// - /// - protected SocketMessageType Receiving() - { - if (_Socket is null) return SocketMessageType.Unknown; - SocketMessageType result = SocketMessageType.Unknown; - try - { - SocketObject[] ServerMessages = GetServerMessage(); - - foreach (SocketObject ServerMessage in ServerMessages) - { - SocketMessageType type = ServerMessage.SocketType; - object[] objs = ServerMessage.Parameters; - result = type; - switch (type) - { - case SocketMessageType.RunTime_Connect: - if (!SocketHandler_Connect(ServerMessage)) return SocketMessageType.Unknown; - break; - - case SocketMessageType.RunTime_Disconnect: - SocketHandler_Disconnect(ServerMessage); - break; - - case SocketMessageType.RunTime_HeartBeat: - if (_Socket != null && _Socket.Connected) - { - SocketHandler_HeartBeat(ServerMessage); - } - break; - - case SocketMessageType.Unknown: - default: - break; - } - } - } - catch (Exception e) - { - // 报错中断服务器连接 - Error(e); - } - return result; - } - - /// - /// 连接服务器的处理方法 - /// - /// - /// - protected abstract bool SocketHandler_Connect(SocketObject ServerMessage); - - /// - /// 与服务器断开连接的处理方法 - /// - /// - protected abstract void SocketHandler_Disconnect(SocketObject ServerMessage); - - /// - /// 心跳检测处理方法 - /// - /// - protected abstract void SocketHandler_HeartBeat(SocketObject ServerMessage); - } -} diff --git a/Model/SocketHandlerModel.cs b/Model/SocketHandlerModel.cs deleted file mode 100644 index b4e291a..0000000 --- a/Model/SocketHandlerModel.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Milimoe.FunGame.Core.Interface.Base; -using Milimoe.FunGame.Core.Library.Common.Architecture; -using Milimoe.FunGame.Core.Library.Common.Network; -using Milimoe.FunGame.Core.Service; - -namespace Milimoe.FunGame.Core.Model -{ - /// - /// 继承 AsyncAwaiter 用法: - /// 1、调用Socket.Send()前,请设置为等待状态:SetWorking(); - /// 2、调用Socket.Send() == Success后,请等待任务完成:WaitForWorkDone(); - /// 3、在其他任何地方修改Working状态,均会使任务终止。 - /// - public class SocketHandlerModel : AsyncAwaiter, ISocketHandler, IDisposable - { - /// - /// 接收到的SocketObject实例 - /// - protected override SocketObject Work { get; set; } - - /// - /// Socket - /// - private readonly Socket _Socket; - - /// - /// 继承请调用base构造 - /// - /// Socket - public SocketHandlerModel(Socket? socket) - { - if (socket != null) - { - _Socket = socket; - socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler)); - } - else throw new SocketCreateReceivingException(); - } - - /// - /// 继承请重写此方法 - /// - /// SocketObject - public virtual void SocketHandler(SocketObject SocketObject) - { - - } - - /// - /// 判断是否已经Disposed - /// - private bool IsDisposed = false; - - /// - /// 公开的Dispose方法 - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// 关闭时 - /// - /// - protected void Dispose(bool Disposing) - { - if (!IsDisposed) - { - if (Disposing) - { - _Socket.BindEvent(new SocketManager.SocketReceiveHandler(SocketHandler), true); - } - } - IsDisposed = true; - } - } -}