using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using QFramework; using System; namespace TCPClientTools { public class TCPMangerArchitecture : Architecture { protected override void Init() { this.RegisterUtility(new TCPUtility()); this.RegisterModel(new TCPEventModel()); } } //统筹管理TCP的命令池以及相关链接信息 public class TCPEventModel : AbstractModel, ICanSendCommand,ICanRegisterEvent { public IOCContainer mCommandContainer = new IOCContainer(); public UnityStringEvent onTCPRecived = new UnityStringEvent(); private TCPLinkState tcpState = TCPLinkState.NoIp; private string tcpAddress = ""; private int tcpPort = 0; public string myAddress = ""; protected override void OnInit() { myAddress = this.GetUtility().GetIP(); this.RegisterEvent(e=> { setTCPState(TCPLinkState.LinkTimeOut); this.GetUtility().CloseTCPClient(); }); } public void sendResponseCommand(string json) where T : ITCPResponse,new() { if (mCommandContainer.Get>()==null) { mCommandContainer.Register(new ExcuteResponseCommand(new T())); } mCommandContainer.Get>().setJson(json); this.SendCommand(mCommandContainer.Get>()); } /// /// 开启接收指定数据 /// /// 数据格式类型 public void onReceive() where T : ITCPResponse, new() { onTCPRecived.AddListener(sendResponseCommand); } /// /// 关闭接收指定数据 /// /// 数据格式类型 public void offReceive() where T : ITCPResponse, new() { onTCPRecived.RemoveListener(sendResponseCommand); } /// /// 发送数据 /// /// 数据类型 /// 请求数据 public void sendRequestCommand(T request)where T : ITCPRequest { if (mCommandContainer.Get>() == null) { mCommandContainer.Register(new SendRequestCommand(request)); } mCommandContainer.Get>().setRequest(request); this.SendCommand(mCommandContainer.Get>()); } public void setTCPState(TCPLinkState state) { this.tcpState = state; this.SendEvent(new TCPStateChangedEvent(state)); } public TCPLinkState getState() { return this.tcpState; } /// /// 设置对应IP,设置完毕后,自动进入链接状态(此时需要用户手动监听是否要进行链接服务器) /// /// ip地址 /// 端口号 public void setIP(string ip,int port) { this.tcpAddress = ip; this.tcpPort = port; //此处可以加ip校验 Debug.LogWarning("此处未进行ip以及端口号校验,日后有需求可以增加"); setTCPState(TCPLinkState.Linking); } /// /// 与服务端建立链接 /// public void linkServer() { if (tcpState == TCPLinkState.Linking) { if (!this.GetUtility().isOpenTCP) { bool isSuccess = this.GetUtility().StartTCPClient(tcpAddress, tcpPort); if (isSuccess) { setTCPState(TCPLinkState.LinkSucess); } else { setTCPState(TCPLinkState.LinkFaild); } } } } /// /// 与服务端断开链接 /// public void closeServer() { if (tcpState == TCPLinkState.LinkSucess) { if (this.GetUtility().isOpenTCP) { this.GetUtility().CloseTCPClient(); setTCPState(TCPLinkState.NoIp); } } } } #region Command /// /// 处理响应数据,添加对应的Command进行处理,需要提前生成命令池 /// /// 响应数据格式 public class ExcuteResponseCommand : AbstractCommand where TResponse : ITCPResponse { public string json; private TResponse response; public ExcuteResponseCommand(TResponse response) { if (this.response == null) { this.response = response; } } protected override void OnExecute() { bool isSet = response.trySetData(json); if (isSet) { Debug.Log("Received:" + response.toJson() + response.GetType()); this.SendEvent(new ResponseMsgEvent(response)); } } public void setJson(string json) { this.json = json; } } public class SendRequestCommand : AbstractCommand where TRequest : ITCPRequest { public TRequest request; public SendRequestCommand(TRequest request) { this.request = request; } protected override void OnExecute() { if (this.GetUtility().isOpenTCP) { this.GetUtility().sendData(request.toJson()); } else { Debug.LogWarning("请先开启TCP链接"); } //throw new NotImplementedException(); } public void setRequest(TRequest request) { this.request = request; } } #endregion #region interface public interface ITCPResponse { string toJson(); /// /// 尝试填充数据,如果json不合法,则返回false,忽略该条数据响应 /// /// /// bool trySetData(string json); string getException(); } public interface ITCPRequest { string toJson(); } #endregion #region AbstractClass /// /// 使用抽象类时,必须满足可序列化 /// [Serializable] public abstract class AbstractTCPResponse:ITCPResponse { private string exceptionMsg; public virtual string toJson() { return JsonUtility.ToJson(this,true); } public virtual bool trySetData(string json) { try { JsonUtility.FromJsonOverwrite(json, this); return true; } catch (Exception e) { exceptionMsg = e.ToString(); return false; } } public string getException() { return exceptionMsg; } } #endregion #region enum public enum TCPLinkState { NoIp = 0, Linking = 1, LinkFaild = 2, LinkSucess = 3, LinkTimeOut = 4 } #endregion #region event public struct ResponseMsgEvent { public ITCPResponse res; public ResponseMsgEvent(ITCPResponse res_) { res = res_; } }; public struct TCPStateChangedEvent { public TCPLinkState state; public TCPStateChangedEvent(TCPLinkState state_) { state = state_; } } public struct onLinkException { public string exceptionMsg; public onLinkException(string exceptionMsg_) { exceptionMsg = exceptionMsg_; } } #endregion [Serializable] public class UnityStringEvent : UnityEvent { } }