using System; using System.Collections; using System.Collections.Generic; using JXSoft; using QFrameworkCP; using UnityEngine; using UnityEngine.Events; namespace JXSoft { //任何通讯类围绕DataEventModel进行 public abstract class DataEventModel : AbstractModel { //管理消息收发响应控制 public IOCContainer mCommandContainer = new IOCContainer(); //管理连接状态响应 public Dictionary mLinkStateContainer = new Dictionary(); public UnityStringEvent onDataRecived = new UnityStringEvent(); public Color printColor = Color.white; #region ReceiveFunctions public void sendResponseCommand(string json) where T : IResponse, new() { //如果找不到对应命令,则添加命令 if (mCommandContainer.Get>() == null) { mCommandContainer.Register(new ExcuteResponseCommand(new T())); } //找到命令后添加命令 mCommandContainer.Get>().setJson(json); this.SendCommand(mCommandContainer.Get>()); } /// /// 开启接收指定数据 /// /// 数据格式类型 public void onReceive() where T : IResponse, new() { onDataRecived.AddListener(sendResponseCommand); } /// /// 关闭接收指定数据 /// /// 数据格式类型 public void offReceive() where T : IResponse, new() { onDataRecived.RemoveListener(sendResponseCommand); } #endregion #region RequestFunctions /// /// 发送数据 /// /// 数据类型 /// 请求数据 public void sendRequestCommand(T request) where T : IRequest { if (mCommandContainer.Get>() == null) { mCommandContainer.Register(new SendRequestCommand(request)); } mCommandContainer.Get>().setRequest(request); this.SendCommand(mCommandContainer.Get>()); } #endregion #region LinkStatusManage public abstract void setLinkState(int linkState); public abstract int getLinkState(); public void transfromLinkState(TLinkState linkState) where TLinkState : ILinkState, new() { if (mLinkStateContainer.ContainsKey(getLinkState())) { bool isSuccess = mLinkStateContainer[getLinkState()].transform(linkState); if (isSuccess) { this.setLinkState(linkState.getLinkState()); } else { Debug.LogWarning("Transform Faild!"); } } } public void transfromLinkState() where TLinkState : ILinkState, new() { TLinkState linkState = new TLinkState(); transfromLinkState(linkState); } public void registerLinkState(ILinkState linkState) { if (mLinkStateContainer.ContainsKey(linkState.getLinkState())) { mLinkStateContainer[linkState.getLinkState()] = linkState; } else { mLinkStateContainer.Add(linkState.getLinkState(), linkState); } } #endregion } #region Command /// /// 处理响应数据,添加对应的Command进行处理,需要提前生成命令池 /// /// 响应数据格式 public class ExcuteResponseCommand : AbstractCommand where TResponse : IResponse { public string json; private TResponse response; private Color printColor = Color.white; 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.toProtocolData() + response.GetType()); this.SendEvent(new ResponseMsgEvent(response)); } } public void setJson(string json) { this.json = json; } } /// /// 发送数据 /// /// 发送数据格式 public class SendRequestCommand : AbstractCommand where TRequest : IRequest { public TRequest request; public SendRequestCommand(TRequest request) { this.request = request; } protected override void OnExecute() { this.SendEvent(new RequestMsgEvent(request)); } public void setRequest(TRequest request) { this.request = request; } } #endregion #region interface public interface IResponse { /// /// 此处用于截获接收到的数据,建议作为调试依据 /// /// string toProtocolData(); /// /// 尝试填充数据,如果不符合相关协议规则,建议返回false,如果此处返回为false,则忽略该条数据响应。 /// /// 协议数据格式 /// bool trySetData(string protocolData); /// /// 如果接收到信息定性为异常信息,获取异常信息 /// /// 异常信息结果 string getException(); } public interface IRequest { //按照协议定义发送格式,转换为字符串发送 string toProtocolData(); } public interface ILinkState { //当前链接状态 int getLinkState(); /// /// 转换到xx状态 /// /// 目标链接状态 /// 是否成功 bool transform(ILinkState invokeState); } #endregion #region AbstractClass /// /// 使用抽象类时,必须满足可序列化 /// [Serializable] public abstract class AbstractResponse : IResponse { private string exceptionMsg; public virtual string toProtocolData() { 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 event public struct ResponseMsgEvent { public IResponse res; public ResponseMsgEvent(IResponse res_) { res = res_; } }; public struct RequestMsgEvent { public IRequest req; public RequestMsgEvent(IRequest req_) { req = req_; } } public struct LinkStateChangedEvent { public int linkState; public LinkStateChangedEvent(int linkState_) { linkState = linkState_; } } #endregion [Serializable] public class UnityStringEvent : UnityEvent { } } /// /// this Package improved a base example of link to server /// you can also create class implements ILinkState. /// namespace BaseLinkState { #region enum public enum LinkStateDefault { NoLink = 0, LinkSuccess = 1, LinkFaild = 2, LinkTimeOut = 3 } #endregion #region LinkState public abstract class StateNoLink : ILinkState { public int getLinkState() { return (int)LinkStateDefault.NoLink; } public bool transform(ILinkState invokeState) { bool transformResult = false; switch (invokeState.getLinkState()) { case (int)LinkStateDefault.LinkSuccess: linkToServer(); break; default: Debug.LogWarning("No such transform fucntion!"); break; } return transformResult; } public abstract bool linkToServer(); } public class StateLinkSuccess : ILinkState { public int getLinkState() { return (int)LinkStateDefault.LinkSuccess; } public bool transform(ILinkState invokeState) { throw new NotImplementedException(); } } public class StateLinkFaild :ILinkState{ public int getLinkState() { return (int)LinkStateDefault.LinkFaild; } public bool transform(ILinkState invokeState) { throw new NotImplementedException(); } } public class StateLinkTimeOut :ILinkState{ public int getLinkState() { return (int)LinkStateDefault.LinkTimeOut; } public bool transform(ILinkState invokeState) { throw new NotImplementedException(); } } #endregion }