|
|
|
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<int,ILinkState> mLinkStateContainer = new Dictionary<int,ILinkState>();
|
|
|
|
public UnityStringEvent onDataRecived = new UnityStringEvent();
|
|
|
|
public Color printColor = Color.white;
|
|
|
|
|
|
|
|
#region ReceiveFunctions
|
|
|
|
public void receiveResponse<T>(string json) where T : IResponse, new()
|
|
|
|
{
|
|
|
|
//如果找不到对应命令,则添加命令
|
|
|
|
if (mCommandContainer.Get<ExcuteResponseCommand<T>>() == null)
|
|
|
|
{
|
|
|
|
mCommandContainer.Register(new ExcuteResponseCommand<T>(new T()));
|
|
|
|
}
|
|
|
|
//找到命令后添加命令
|
|
|
|
mCommandContainer.Get<ExcuteResponseCommand<T>>().setJson(json);
|
|
|
|
this.SendCommand(mCommandContainer.Get<ExcuteResponseCommand<T>>());
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
|
|
/// 开启接收指定数据
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="T">数据格式类型</typeparam>
|
|
|
|
public void onReceive<T>() where T : IResponse, new()
|
|
|
|
{
|
|
|
|
onDataRecived.AddListener(receiveResponse<T>);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
|
|
/// 关闭接收指定数据
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="T">数据格式类型</typeparam>
|
|
|
|
public void offReceive<T>() where T : IResponse, new()
|
|
|
|
{
|
|
|
|
onDataRecived.RemoveListener(receiveResponse<T>);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region RequestFunctions
|
|
|
|
/// <summary>
|
|
|
|
/// 发送数据
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="T">数据类型</typeparam>
|
|
|
|
/// <param name="request">请求数据</param>
|
|
|
|
public void sendRequest<T>(T request) where T : IRequest
|
|
|
|
{
|
|
|
|
if (mCommandContainer.Get<SendRequestCommand<T>>() == null)
|
|
|
|
{
|
|
|
|
mCommandContainer.Register(new SendRequestCommand<T>(request));
|
|
|
|
}
|
|
|
|
mCommandContainer.Get<SendRequestCommand<T>>().setRequest(request);
|
|
|
|
this.SendCommand(mCommandContainer.Get<SendRequestCommand<T>>());
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region LinkStatusManage
|
|
|
|
public abstract void setLinkState(int linkState);
|
|
|
|
public abstract int getLinkState();
|
|
|
|
|
|
|
|
public void transfromLinkState<TLinkState>(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<TLinkState>() 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
|
|
|
|
/// <summary>
|
|
|
|
/// 处理响应数据,添加对应的Command进行处理,需要提前生成命令池
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="TResponse">响应数据格式</typeparam>
|
|
|
|
public class ExcuteResponseCommand<TResponse> : 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 发送数据
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="TRequest">发送数据格式</typeparam>
|
|
|
|
public class SendRequestCommand<TRequest> : 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
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// 此处用于截获接收到的数据,建议作为调试依据
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
string toProtocolData();
|
|
|
|
/// <summary>
|
|
|
|
/// 尝试填充数据,如果不符合相关协议规则,建议返回false,如果此处返回为false,则忽略该条数据响应。
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="protocolData">协议数据格式</param>
|
|
|
|
/// <returns></returns>
|
|
|
|
bool trySetData(string protocolData);
|
|
|
|
/// <summary>
|
|
|
|
/// 如果接收到信息定性为异常信息,获取异常信息
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>异常信息结果</returns>
|
|
|
|
string getException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface IRequest
|
|
|
|
{
|
|
|
|
//按照协议定义发送格式,转换为字符串发送
|
|
|
|
string toProtocolData();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public interface ILinkState {
|
|
|
|
//当前链接状态
|
|
|
|
int getLinkState();
|
|
|
|
/// <summary>
|
|
|
|
/// 转换到xx状态
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="invokeState">目标链接状态</param>
|
|
|
|
/// <returns>是否成功</returns>
|
|
|
|
bool transform(ILinkState invokeState);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region AbstractClass
|
|
|
|
/// <summary>
|
|
|
|
/// 使用抽象类时,必须满足可序列化
|
|
|
|
/// </summary>
|
|
|
|
[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 Extention
|
|
|
|
public static class CanRegistMessageExtention {
|
|
|
|
public static IUnRegister RegisterMessageEvent<TResponse>(this ICanRegisterEvent self, Action<TResponse> onEvent)
|
|
|
|
{
|
|
|
|
return self.GetArchitecture().RegisterEvent<ResponseMsgEvent>(e=> {
|
|
|
|
if (e.res.GetType() == typeof(TResponse)) {
|
|
|
|
onEvent.Invoke((TResponse)e.res);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#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<string>
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// this Package improved a base example of link to server
|
|
|
|
/// you can also create class implements ILinkState.
|
|
|
|
/// </summary>
|
|
|
|
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
|
|
|
|
|
|
|
|
}
|