6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
1359 lines
48 KiB
C#
1359 lines
48 KiB
C#
/*
|
|
* 由SharpDevelop创建。
|
|
* 用户: Administrator
|
|
* 日期: 2018-10-30
|
|
* 时间: 16:00
|
|
*
|
|
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using GameData;
|
|
using GameDAL;
|
|
using MrWu.Debug;
|
|
using MrWu.RabbitMQ;
|
|
using RabbitMQ.Client;
|
|
using Server.Data.Module;
|
|
using Server.Module;
|
|
using Server.MQ;
|
|
using Server.Pack;
|
|
|
|
namespace Server.MQ
|
|
{
|
|
/*
|
|
* 设计方案
|
|
*
|
|
* exit_game_1 : 提示玩家网络故障,踢出玩家所在的游戏
|
|
*
|
|
*
|
|
*
|
|
* */
|
|
|
|
/// <summary>
|
|
/// 消息管理 工厂
|
|
/// </summary>
|
|
public abstract class IGlobalFactory
|
|
{
|
|
/// <summary>
|
|
/// 创建消息管理
|
|
/// </summary>
|
|
public abstract void CreateGlobalMQ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// rabbit消息投递管理类
|
|
/// </summary>
|
|
public class GlobalMQ : IGlobalMQ
|
|
{
|
|
/// <summary>
|
|
/// 消息管理工厂
|
|
/// </summary>
|
|
public class Factory : IGlobalFactory
|
|
{
|
|
/// <summary>
|
|
/// 创建消息管理类
|
|
/// </summary>
|
|
public override void CreateGlobalMQ()
|
|
{
|
|
if (instance == null)
|
|
instance = new GlobalMQ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// rabbit消息投递管理类单例
|
|
/// </summary>
|
|
public static GlobalMQ instance { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// 失败原因的 key 消息未发送成功(502) 消息未被路由(503) 消息被扔弃(504)
|
|
/// </summary>
|
|
public const string failCode = "failCode";
|
|
|
|
/// <summary>
|
|
/// 应该由谁来处理这个未被路由或被扔弃的包
|
|
/// </summary>
|
|
public const string doFailKey = "doFail";
|
|
|
|
/// <summary>
|
|
/// 应该由哪个节点来处理扔弃的包
|
|
/// </summary>
|
|
public const string doFailNodeNum = "doFailNodeNum";
|
|
|
|
/// <summary>
|
|
/// 处理失败的标记-有标记的才会处理,没有的会被扔弃
|
|
/// </summary>
|
|
public const string failTagKey = "failTag";
|
|
|
|
/// <summary>
|
|
/// 发送成功要做的事
|
|
/// </summary>
|
|
public const string successTagKey = "successTag";
|
|
|
|
/// <summary>
|
|
/// 构造
|
|
/// </summary>
|
|
protected GlobalMQ()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 消息管理
|
|
/// </summary>
|
|
protected RabbitManager rabbit { get; private set; }
|
|
|
|
/// <summary>
|
|
/// rpc客户端
|
|
/// </summary>
|
|
public RpcClient rpcClient { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int GetNoAckCount()
|
|
{
|
|
if (rabbit == null)
|
|
return 0;
|
|
return rabbit.NoAckCount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送完成事件
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
public virtual bool SendOK(Message msg)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送失败
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
public virtual void SendFail(Message msg)
|
|
{
|
|
return;
|
|
if (msg.userData == null || !msg.userData.ContainsKey(failCode)
|
|
|| !msg.userData.ContainsKey(failTagKey) || !msg.userData.ContainsKey(doFailKey))
|
|
{
|
|
if (!msg.noAck && msg.deliveryTag > 0)
|
|
msg.Ack();
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
string dofailTag = msg.userData[failTagKey].ToString();
|
|
|
|
//switch(dofailTag){
|
|
|
|
// };
|
|
msg.Ack();
|
|
Debug.Log("处理发送失败的消息:" + dofailTag + "," + msg);
|
|
return;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Error("处理发送失败消息时出现错误,msg:{0},exception:{1}", msg, e.ToString());
|
|
msg.NAck();
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 链接阻塞
|
|
/// </summary>
|
|
public void ConnectionBlocked()
|
|
{
|
|
//if (rabbit == null)
|
|
// return;
|
|
//rabbit.ConnectionBlocked();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 解除链接阻塞
|
|
/// </summary>
|
|
public void ConnectionUnBlocked()
|
|
{
|
|
//if (rabbit == null)
|
|
// return;
|
|
//rabbit.ConnectionUnBlocked();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送消息
|
|
/// </summary>
|
|
/// <param name="msg">消息</param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
public virtual void SendMessage(Message msg, bool isAutoFree)
|
|
{
|
|
//CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, isAutoFree, Recv2ReturnDescription.One_Void);//
|
|
rabbit.BasicPublish(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送消息并要得到发送结果
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
///<param name="isAutoFree">是否自动释放</param>
|
|
public virtual bool SendMessage_Result(Message msg, bool isAutoFree)
|
|
{
|
|
// return CheckFiltersAndPublish(rabbit.BasicPublish_Result, msg, isAutoFree, Recv2ReturnDescription.One_Bool);//
|
|
return rabbit.BasicPublish_Result(msg, isAutoFree);
|
|
}
|
|
|
|
private ModuleUtile myUtile;
|
|
|
|
/// <summary>
|
|
/// rabbit消息管理启动
|
|
/// </summary>
|
|
/// <param name="config">rabbit配置</param>
|
|
/// <param name="utile">模块</param>
|
|
/// <param name="DelExists">是否删除已存在的路由,大升级要使用到,路由规则已改</param>
|
|
/// <returns>启动成功还是失败</returns>
|
|
public bool StartModule(RabbitConfig config, ModuleUtile utile, bool DelExists = false)
|
|
{
|
|
if (rabbit != null)
|
|
return false;
|
|
|
|
myUtile = utile;
|
|
RountingManager.instance.Start((ModuleType)myUtile.id, myUtile.nodeNum);
|
|
AddConfig(config, utile, DelExists);
|
|
rabbit = new RabbitManager();
|
|
|
|
rabbit.SendResult += SendResult;
|
|
rabbit.notRoutingOk += NotRoutingOk;
|
|
rabbit.Start(config);
|
|
|
|
rpcClient = rabbit.CreateRpcClient();
|
|
|
|
CreateConsumer();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加配置
|
|
/// </summary>
|
|
/// <param name="config">配置</param>
|
|
/// <param name="utile">当前模块</param>
|
|
/// <param name="delExists">是否声明前先删除模块</param>
|
|
public virtual void AddConfig(RabbitConfig config, ModuleUtile utile, bool delExists)
|
|
{
|
|
string exbak = "Expired"; //过期的交换机 过期的队列
|
|
|
|
ExchangeInfo[] exchangeInfos = new ExchangeInfo[3];
|
|
ExchangeInfo info = new ExchangeInfo();
|
|
info.name = RountingManager.instance.clubsterRouteName;
|
|
info.type = "topic";
|
|
info.durable = true;
|
|
info.autodelete = false;
|
|
info.delExists = delExists;
|
|
// info.alternate_exchange = exbak;
|
|
|
|
exchangeInfos[0] = info;
|
|
|
|
info = new ExchangeInfo();
|
|
info.name = RountingManager.instance.clusterAllRouteName;
|
|
info.type = "fanout";
|
|
info.durable = true;
|
|
info.autodelete = false;
|
|
info.delExists = delExists;
|
|
// info.alternate_exchange = exbak;
|
|
|
|
exchangeInfos[1] = info;
|
|
|
|
info = new ExchangeInfo();
|
|
info.name = RountingManager.instance.clusterNodeOne;
|
|
info.type = "direct";
|
|
info.durable = true;
|
|
info.autodelete = false;
|
|
info.delExists = delExists;
|
|
// info.alternate_exchange = exbak;
|
|
|
|
exchangeInfos[2] = info;
|
|
|
|
config.exchanges = exchangeInfos;
|
|
|
|
QueueInfo[] queueinfos = new QueueInfo[2];
|
|
QueueInfo queue = new QueueInfo();
|
|
queue.name = RountingManager.instance.queueNode;
|
|
queue.durable = true;
|
|
queue.exclusive = false;
|
|
queue.startClear = false;
|
|
queue.delExists = delExists;
|
|
queue.autodelete = false;
|
|
queue.x_message_ttl = 0;
|
|
// queue.x_dead_letter_exchange = exbak;
|
|
// queue.x_dead_routing_key = "expire";
|
|
queueinfos[0] = queue;
|
|
|
|
queue = new QueueInfo();
|
|
queue.name = RountingManager.instance.queueEveryOne;
|
|
queue.durable = true;
|
|
queue.exclusive = false;
|
|
queue.startClear = false;
|
|
queue.delExists = delExists;
|
|
queue.autodelete = false;
|
|
queue.x_message_ttl = 0;
|
|
// queue.x_dead_letter_exchange = exbak;
|
|
// queue.x_dead_routing_key = "expire";
|
|
queueinfos[1] = queue;
|
|
|
|
config.queues = queueinfos;
|
|
|
|
BindInfo[] bindInfos = new BindInfo[6];
|
|
BindInfo bindInfo = new BindInfo();
|
|
bindInfo.destination = RountingManager.instance.queueNode;
|
|
bindInfo.source = RountingManager.instance.clusterAllRouteName;
|
|
bindInfo.routingkey = RountingManager.instance.routeallkey;
|
|
bindInfo.bindType = "queue";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[0] = bindInfo;
|
|
|
|
bindInfo = new BindInfo();
|
|
bindInfo.destination = RountingManager.instance.queueNode;
|
|
bindInfo.source = RountingManager.instance.clusterNodeOne;
|
|
bindInfo.routingkey = RountingManager.instance.nodeRouteKey;
|
|
bindInfo.bindType = "queue";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[1] = bindInfo;
|
|
|
|
bindInfo = new BindInfo();
|
|
bindInfo.destination = RountingManager.instance.queueEveryOne;
|
|
bindInfo.source = RountingManager.instance.clubsterRouteName;
|
|
bindInfo.routingkey = RountingManager.instance.routeEveryOneKey;
|
|
bindInfo.bindType = "queue";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[2] = bindInfo;
|
|
|
|
bindInfo = new BindInfo();
|
|
bindInfo.destination = RountingManager.instance.clubsterRouteName;
|
|
bindInfo.source = RountingManager.AllServerRouteName;
|
|
bindInfo.routingkey = RountingManager.instance.routeallkey;
|
|
bindInfo.bindType = "exchange";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[3] = bindInfo;
|
|
|
|
bindInfo = new BindInfo();
|
|
bindInfo.destination = RountingManager.instance.clusterAllRouteName;
|
|
bindInfo.source = RountingManager.instance.clubsterRouteName;
|
|
bindInfo.routingkey = RountingManager.instance.routeallkey;
|
|
bindInfo.bindType = "exchange";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[4] = bindInfo;
|
|
|
|
bindInfo = new BindInfo();
|
|
|
|
bindInfo.destination = RountingManager.instance.clusterNodeOne;
|
|
bindInfo.source = RountingManager.instance.clubsterRouteName;
|
|
bindInfo.routingkey = RountingManager.instance.nodeRouteMatch;
|
|
bindInfo.bindType = "exchange";
|
|
|
|
Debug.Info("绑定信息,目标:" + bindInfo.destination + ",源:" + bindInfo.source + ",路由键:" + bindInfo.routingkey);
|
|
|
|
bindInfos[5] = bindInfo;
|
|
|
|
config.binds = bindInfos;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否开启接收消息日志
|
|
/// </summary>
|
|
public static bool openMsgLog;
|
|
|
|
/// <summary>
|
|
/// 接收到消息
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
public virtual void ReciveMessage(Message msg)
|
|
{
|
|
if (openMsgLog)
|
|
Debug.Log("接收到消息:" + msg.ToString());
|
|
|
|
if (msg.userData != null && msg.userData.ContainsKey(failCode))
|
|
{
|
|
//有错误信息的消息,处理错误
|
|
SendFail(msg);
|
|
MessagePool.PutMessage(ref msg);
|
|
}
|
|
else
|
|
{
|
|
//正常收包
|
|
AddMessage(msg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 未被路由的消息 事件过来的
|
|
/// </summary>
|
|
/// <param name="msg">消息</param>
|
|
protected void NotRoutingOk(Message msg)
|
|
{
|
|
return;
|
|
DoFail(msg, 503);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分发处理失败的消息
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <param name="FailCode"></param>
|
|
protected void DoFail(Message msg, int FailCode)
|
|
{
|
|
try
|
|
{
|
|
if (!msg.userData.ContainsKey(failTagKey)) //没有标记不处理
|
|
return;
|
|
if (msg.userData.ContainsKey(failCode))
|
|
{
|
|
//已经有错误标记,说明已经进入了此流程-并投递给别人使用,当时又出了问题避免死循环不再处理,记录日志
|
|
Debug.Error("消息发送失败,并未被处理.failCode:{0},msg:{1}", msg.userData[failCode], msg);
|
|
return;
|
|
}
|
|
|
|
//先赋值失败原因 未发送成功
|
|
msg.userData[failCode] = FailCode;
|
|
|
|
bool isMyFail = false;
|
|
|
|
if (msg.userData.ContainsKey(doFailKey))
|
|
{
|
|
//没赋值处理失败的人就是自己处理
|
|
object tmp = msg.userData[doFailKey];
|
|
int id = (int)tmp;
|
|
if (id == myUtile.id)
|
|
{
|
|
//是本模块处理的
|
|
|
|
if (msg.userData.ContainsKey(doFailNodeNum))
|
|
{
|
|
//如果指定了处理的节点
|
|
int nodenum = (int)msg.userData[doFailNodeNum];
|
|
if (nodenum == myUtile.id)
|
|
isMyFail = true;
|
|
}
|
|
else
|
|
isMyFail = true;
|
|
|
|
if (isMyFail) //处理发送失败的错误
|
|
SendFail(msg);
|
|
}
|
|
}
|
|
|
|
if (!isMyFail)
|
|
{
|
|
//投递给处理失败的模块队列
|
|
//待补待补
|
|
|
|
//处理错误模块的id
|
|
int nodeid = (int)msg.userData[doFailKey];
|
|
|
|
bool isNAck = false;
|
|
|
|
if (msg.userData.ContainsKey(doFailNodeNum))
|
|
{
|
|
//指定了节点-投递给指定节点
|
|
int nodenum = (int)msg.userData[doFailNodeNum];
|
|
msg.SendResult = null;
|
|
if (!DeliveryOne_Result(new ServerNode(nodeid, nodenum), msg, false))
|
|
{
|
|
//发不出去就拒收,下次再处理
|
|
isNAck = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//没指定节点,投递给任意节点
|
|
msg.SendResult = null;
|
|
if (!DeliveryEveryOne_Result(nodeid, msg, false))
|
|
{
|
|
isNAck = true;
|
|
}
|
|
}
|
|
|
|
if (!msg.noAck && msg.deliveryTag > 0)
|
|
{
|
|
if (isNAck)
|
|
msg.NAck();
|
|
else
|
|
msg.Ack();
|
|
}
|
|
}
|
|
|
|
|
|
Debug.Error("发送消息失败:" + msg.ToString());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Error("分发处理任务错误时失败:" + e.ToString());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送结果 事件过来的
|
|
/// </summary>
|
|
/// <param name="msg">消息</param>
|
|
protected void SendResult(Message msg)
|
|
{
|
|
if (msg.success)
|
|
{
|
|
//发送成功
|
|
if (msg.userData == null || !msg.userData.ContainsKey(successTagKey))
|
|
{
|
|
//没有标记 不处理
|
|
return;
|
|
}
|
|
|
|
SendOK(msg);
|
|
}
|
|
else
|
|
{
|
|
//发送失败
|
|
DoFail(msg, 502);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 单独的消费者
|
|
/// </summary>
|
|
private Consumer exclusiveConsumer;
|
|
|
|
/// <summary>
|
|
/// 共享的消费者
|
|
/// </summary>
|
|
private Consumer sharedConsumer;
|
|
|
|
/// <summary>
|
|
/// 处理错误消息的消费者
|
|
/// </summary>
|
|
private Consumer doFailConsumer;
|
|
|
|
/// <summary>
|
|
/// 过期的消息队列
|
|
/// </summary>
|
|
private const string exipreQueue = "expired";
|
|
|
|
/// <summary>
|
|
/// 创建消费者
|
|
/// </summary>
|
|
public virtual void CreateConsumer()
|
|
{
|
|
//消费者有2 独有消息与共有消息
|
|
Consumer consumer = new Consumer();
|
|
consumer.noAck = false;
|
|
consumer.noLoacl = false;
|
|
consumer.queue = RountingManager.instance.queueNode;
|
|
consumer.exclusive = true;
|
|
consumer.Receive = ReciveMessage;
|
|
exclusiveConsumer = consumer;
|
|
rabbit.AddConsumer(consumer);
|
|
|
|
consumer = new Consumer();
|
|
consumer.noAck = false;
|
|
consumer.noLoacl = false;
|
|
consumer.queue = RountingManager.instance.queueEveryOne;
|
|
consumer.exclusive = false;
|
|
consumer.Receive = ReciveMessage;
|
|
//consumer.prefetchCount = 3;
|
|
sharedConsumer = consumer;
|
|
rabbit.AddConsumer(sharedConsumer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加错误消息的消费者
|
|
/// </summary>
|
|
public void AddFailConsumer()
|
|
{
|
|
return;
|
|
Consumer consumer = new Consumer();
|
|
consumer.noAck = false;
|
|
consumer.noLoacl = false;
|
|
consumer.queue = exipreQueue;
|
|
consumer.exclusive = false;
|
|
consumer.Receive = NotRoutingOk;
|
|
doFailConsumer = consumer;
|
|
rabbit.AddConsumer(doFailConsumer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移出处理失败消息的消费者
|
|
/// </summary>
|
|
public void RemoveFailConsumer()
|
|
{
|
|
if (doFailConsumer != null)
|
|
rabbit.RemoveConsumer(doFailConsumer);
|
|
doFailConsumer = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关闭模块
|
|
/// </summary>
|
|
public void Close()
|
|
{
|
|
if (rabbit == null)
|
|
return;
|
|
rabbit.Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等待处理的消息
|
|
/// </summary>
|
|
private readonly ConcurrentQueue<WaitBeMsg> _waitBeMessages = new ConcurrentQueue<WaitBeMsg>();
|
|
|
|
public int GteMessageCnt()
|
|
{
|
|
return _waitBeMessages.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 拿一条消息
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public WaitBeMsg GetMessage()
|
|
{
|
|
if (_waitBeMessages.Count > 0 && _waitBeMessages.TryDequeue(out WaitBeMsg msg))
|
|
{
|
|
return msg;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加消息
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
public void AddMessage(Message msg)
|
|
{
|
|
WaitBeMsg tmp = WaitBeMsgPool.GetWaiteBeMsg(msg);
|
|
_waitBeMessages.Enqueue(tmp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加消息
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
public void AddMessage(WaitBeMsg msg)
|
|
{
|
|
_waitBeMessages.Enqueue(msg);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建消息
|
|
/// </summary>
|
|
/// <param name="jsonmessage">json整包</param>
|
|
/// <param name="failTag">失败标记</param>
|
|
/// <param name="doFail">谁来处理失败标记</param>
|
|
/// <param name="doFailNode">处理失败标记的节点</param>
|
|
/// <param name="successTag">成功标记</param>
|
|
/// <param name="userData"></param>
|
|
/// <returns></returns>
|
|
public static Message CreateMessage(string jsonmessage, string failTag = null, int doFail = -1,
|
|
int doFailNode = -1, string successTag = null, IDictionary<string, object> userData = null)
|
|
{
|
|
Message msg = MessagePool.GetMessage();
|
|
msg.bodystr = jsonmessage;
|
|
IDictionary<string, object> dic = new Dictionary<string, object>();
|
|
if (doFail != -1)
|
|
dic[doFailKey] = doFail;
|
|
if (failTag != null)
|
|
dic[failTagKey] = failTag;
|
|
if (doFailNode != -1)
|
|
dic[doFailNodeNum] = doFailNode;
|
|
if (successTag != null)
|
|
dic[successTagKey] = successTag;
|
|
|
|
msg.userData = dic;
|
|
msg.mandatory = true;
|
|
msg.userData = userData;
|
|
msg.durable = false;
|
|
return msg;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建消息
|
|
/// </summary>
|
|
/// <param name="head">包头</param>
|
|
/// <param name="otherstring">包体字符串</param>
|
|
/// <param name="failTag">发送失败标记</param>
|
|
/// <param name="doFail">处理失败的模块</param>
|
|
/// <param name="doFailNode">处理失败的节点</param>
|
|
/// <param name="successTag">处理成功的标记</param>
|
|
/// <param name="userData"></param>
|
|
/// <returns>消息</returns>
|
|
public static Message CreateMessage(PackHead head, string otherstring, string failTag = null, int doFail = -1,
|
|
int doFailNode = -1, string successTag = null, IDictionary<string, object> userData = null)
|
|
{
|
|
head.sendutil = GlobalMQ.instance.myUtile;
|
|
string message = JsonPack.GetJsonByPack_head(head, otherstring);
|
|
return CreateMessage(message, failTag, doFail, doFailNode, successTag, userData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建消息
|
|
/// </summary>
|
|
/// <param name="head">包头</param>
|
|
/// <param name="data">包数据</param>
|
|
/// <param name="failTag">发送失败的标记</param>
|
|
/// <param name="doFail">处理失败的模块</param>
|
|
/// <param name="doFailNode">处理失败的节点</param>
|
|
/// <param name="successTag">处理成功的标记</param>
|
|
/// <param name="userData"></param>
|
|
/// <returns></returns>
|
|
public static Message CreateMessage(PackHead head, object data = null, string failTag = null, int doFail = -1,
|
|
int doFailNode = -1, string successTag = null, IDictionary<string, object> userData = null)
|
|
{
|
|
head.sendutil = GlobalMQ.instance.myUtile;
|
|
string message = JsonPack.GetJsonByPack(head, data);
|
|
var msg = CreateMessage(message, failTag, doFail, doFailNode, successTag, userData);
|
|
return msg;
|
|
}
|
|
|
|
#region 投递消息 message
|
|
|
|
/// <summary>
|
|
/// 投递消息给一个模块 并需要知道投递结果-只能知道是否投递成功,无法知道是否到达队列
|
|
/// </summary>
|
|
/// <param name="target">目标</param>
|
|
/// <param name="msg">消息</param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
/// <returns>true 表示在线并投递成功 false 表示投递失败或者目标不在线</returns>
|
|
public bool DeliveryOne_Result(ServerNode target, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
if (msg == null)
|
|
return false;
|
|
|
|
if (target == null)
|
|
{
|
|
Debug.Warning("target is null msg:{0}", msg);
|
|
if (isAutoFree)
|
|
MessagePool.PutMessage(ref msg);
|
|
return false;
|
|
}
|
|
|
|
if (myUtile.Equals(target))
|
|
{
|
|
//发给自己的
|
|
GlobalMQ.instance.AddMessage(msg);
|
|
return true;
|
|
}
|
|
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(target.id);
|
|
msg.routingkey = RountingManager.instance.GetNodeRouteKey(target.id, target.nodeNum);
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为空6666:" + msg.bodystr);
|
|
return false;
|
|
}
|
|
|
|
|
|
//return CheckFiltersAndPublish(rabbit.BasicPublish_Result, msg, isAutoFree, Recv2ReturnDescription.One_Bool);//
|
|
return rabbit.BasicPublish_Result(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投递消息给一个模块 不管结果
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
public virtual void DeliveryOne(ServerNode target, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
if (target == null)
|
|
{
|
|
Debug.Warning("target is null msg:{0}", msg);
|
|
return;
|
|
}
|
|
|
|
if (myUtile.Equals(target))
|
|
{
|
|
//发给自己的
|
|
GlobalMQ.instance.AddMessage(msg);
|
|
return;
|
|
}
|
|
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(target.id);
|
|
msg.routingkey = RountingManager.instance.GetNodeRouteKey(target.id, target.nodeNum);
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为空5555:" + msg.bodystr);
|
|
return;
|
|
}
|
|
|
|
//CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, isAutoFree, Recv2ReturnDescription.One_Void);
|
|
rabbit.BasicPublish(msg, isAutoFree);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 群发给任意模块信息
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
/// <returns></returns>
|
|
public bool DeliveryEveryOne_Result(int moduleId, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
msg.routingkey = RountingManager.instance.GetEveryOneRouteKey(moduleId);
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为空444:" + moduleId + "," + msg.bodystr);
|
|
return false;
|
|
}
|
|
|
|
|
|
//return CheckFiltersAndPublish(rabbit.BasicPublish_Result, msg, isAutoFree, Recv2ReturnDescription.EveryOne_Bool);
|
|
return rabbit.BasicPublish_Result(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 群发给任意模块信息
|
|
/// </summary>
|
|
/// <param name="moduleId">目标模块id</param>
|
|
/// <param name="msg">消息内容</param>
|
|
/// <returns>没有绑定该模块则为false 绑定则为true</returns>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
public void DeliveryEveryOne(int moduleId, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
msg.routingkey = RountingManager.instance.GetEveryOneRouteKey(moduleId);
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为空333:" + msg.bodystr);
|
|
return;
|
|
}
|
|
|
|
//CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, isAutoFree, Recv2ReturnDescription.EveryOne_Void);
|
|
rabbit.BasicPublish(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投递这个模块的所有节点
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
public bool DeliveryAll_Result(int moduleId, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
msg.routingkey = RountingManager.instance.routeallkey;
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机与路由键为空!111" + msg.bodystr);
|
|
return false;
|
|
}
|
|
|
|
return CheckFiltersAndPublish(rabbit.BasicPublish_Result, msg, isAutoFree,
|
|
Recv2ReturnDescription.All_Bool); //rabbit.BasicPublish_Result(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投递给这类所有模块
|
|
/// </summary>
|
|
/// <param name="moduleId">目标类模块id</param>
|
|
/// <param name="msg">消息内容</param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
public void DeliveryAll(int moduleId, Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
msg.routingkey = RountingManager.instance.routeallkey;
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机与路由键为空!222:" + msg.bodystr);
|
|
return;
|
|
}
|
|
|
|
//CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, isAutoFree, Recv2ReturnDescription.All_Void);
|
|
rabbit.BasicPublish(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投递给所有模块
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化处理</param>
|
|
public bool DeliverAll_Result(Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.AllServerRouteName;
|
|
msg.routingkey = RountingManager.instance.routeallkey;
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
// Debug.Error("消息的交换机或路由键为空!7777" + msg.bodystr);
|
|
return false;
|
|
}
|
|
|
|
return CheckFiltersAndPublish(rabbit.BasicPublish_Result, msg, isAutoFree,
|
|
Recv2ReturnDescription.All_Bool); //rabbit.BasicPublish_Result(msg, isAutoFree);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投递给所有模块
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree">是否自动释放</param>
|
|
/// <param name="durable">持久化</param>
|
|
public void DeliveryAll(Message msg, bool isAutoFree, bool durable = false)
|
|
{
|
|
msg.exchange = RountingManager.AllServerRouteName;
|
|
msg.routingkey = RountingManager.instance.routeallkey;
|
|
msg.durable = durable;
|
|
|
|
if (string.IsNullOrEmpty(msg.exchange) || string.IsNullOrEmpty(msg.routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为空!8888:" + msg.bodystr);
|
|
return;
|
|
}
|
|
|
|
//CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, true, Recv2ReturnDescription.All_Void);
|
|
rabbit.BasicPublish(msg, isAutoFree);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// RPC Call 方法
|
|
/// </summary>
|
|
/// <param name="target">目标</param>
|
|
/// <param name="message">消息</param>
|
|
/// <param name="waitTime">等待多久</param>
|
|
/// <returns></returns>
|
|
public string Call(ServerNode target, string message, int waitTime = 3000)
|
|
{
|
|
if (target == null)
|
|
{
|
|
Debug.Warning("target is null msg:{0}", message);
|
|
return null;
|
|
}
|
|
|
|
string exchange = RountingManager.instance.GetClusterRoute(target.id);
|
|
string routingkey = RountingManager.instance.GetNodeRouteKey(target.id, target.nodeNum);
|
|
|
|
if (string.IsNullOrEmpty(exchange) || string.IsNullOrEmpty(routingkey))
|
|
{
|
|
Debug.Error("消息的交换机或路由键为 call 5555:" + message);
|
|
return null;
|
|
}
|
|
|
|
return CheckFiltersAndCall(() => rpcClient.Call(exchange, routingkey, message, waitTime), message,
|
|
Recv2ReturnDescription.Call_One_String);
|
|
}
|
|
|
|
/// <summary>
|
|
/// RPC Call 任意一个模块
|
|
/// </summary>
|
|
/// <param name="moduleId">目标id</param>
|
|
/// <param name="message">消息</param>
|
|
/// <param name="waitTime">等待多久</param>
|
|
/// <returns></returns>
|
|
public string Call_EveryOne(int moduleId, string message, int waitTime = 3000)
|
|
{
|
|
string exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
string routingkey = RountingManager.instance.GetEveryOneRouteKey(moduleId);
|
|
|
|
if (string.IsNullOrEmpty(exchange) || string.IsNullOrEmpty(routingkey))
|
|
{
|
|
Debug.Error("消息交换或路由键为 call 6666:" + moduleId + "," + message);
|
|
return null;
|
|
}
|
|
|
|
var ret = CheckFiltersAndCall(() => rpcClient.Call(exchange, routingkey, message, waitTime), message,
|
|
Recv2ReturnDescription.Call_EveryOne_String);
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
/// <param name="head"></param>
|
|
/// <param name="data"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public string Call(ServerNode target, PackHead head, object data = null, int waitTime = 3000)
|
|
{
|
|
string message = JsonPack.GetJsonByPack(head, data);
|
|
return Call(target, message, waitTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rpc call
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
/// <param name="head"></param>
|
|
/// <param name="jsonmessage"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public string Call(ServerNode target, PackHead head, string jsonmessage, int waitTime = 3000)
|
|
{
|
|
string message = JsonPack.GetJsonByPack_head(head, jsonmessage);
|
|
return Call(target, message, waitTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// call 方法
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="head"></param>
|
|
/// <param name="data"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public string Call_EveryOne(int moduleId, PackHead head, object data = null, int waitTime = 3000)
|
|
{
|
|
string message = JsonPack.GetJsonByPack(head, data);
|
|
return Call_EveryOne(moduleId, message, waitTime);
|
|
}
|
|
|
|
/*
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="head"></param>
|
|
/// <param name="data"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public System.Threading.Tasks.Task<string> AsyncCall_EveryOne(int moduleId, ServerHead head, object data = null, int waitTime = 3000) {
|
|
string message = JsonPack.GetJsonByPack(head, data);
|
|
return AsyncCall_EveryOne(moduleId, message, waitTime);
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public System.Threading.Tasks.Task<string> AsyncCall_EveryOne(int moduleId, string message, int waitTime = 3000) {
|
|
string exchange = RountingManager.instance.GetClusterRoute(moduleId);
|
|
string routingkey = RountingManager.instance.GetEveryOneRouteKey(moduleId);
|
|
|
|
if(string.IsNullOrEmpty(exchange) || string.IsNullOrEmpty(routingkey)) {
|
|
Debug.Error("消息交换或路由键为 call 6666:" + message);
|
|
return null;
|
|
}
|
|
var ret = rpcClient.AsyncCall(exchange, routingkey, message, waitTime);
|
|
return ret;
|
|
}
|
|
*/
|
|
|
|
/// <summary>
|
|
/// call 方法
|
|
/// </summary>
|
|
/// <param name="moduleId"></param>
|
|
/// <param name="head"></param>
|
|
/// <param name="jsonmessage"></param>
|
|
/// <param name="waitTime"></param>
|
|
/// <returns></returns>
|
|
public string Call_EveryOne_str(int moduleId, PackHead head, string jsonmessage = null, int waitTime = 3000)
|
|
{
|
|
string message = JsonPack.GetJsonByPack_head(head, jsonmessage);
|
|
return Call_EveryOne(moduleId, message, waitTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// RPC回复
|
|
/// </summary>
|
|
/// <param name="ibp"></param>
|
|
/// <param name="message"></param>
|
|
/// <param name="userData"></param>
|
|
public void CallBack(IBasicProperties ibp, object message, IDictionary<string, object> userData)
|
|
{
|
|
Message msg = MessagePool.GetMessage();
|
|
msg.exchange = string.Empty;
|
|
msg.routingkey = ibp.ReplyTo;
|
|
msg.propertis = rabbit.GetBasicProperties();
|
|
msg.propertis.CorrelationId = ibp.CorrelationId;
|
|
msg.bodystr = JsonPack.GetJson(message);
|
|
msg.userData = userData;
|
|
Debug.Log("RPC回复:" + msg.propertis.CorrelationId);
|
|
|
|
CheckFiltersCallbackAndPublishNoReturn(rabbit.BasicPublish, msg, true, Recv2ReturnDescription.CallBack);
|
|
//rabbit.BasicPublish(msg, true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
/// AddFilter
|
|
/// </summary>
|
|
/// <param name="filter"></param>
|
|
public static void AddFilter(IMQFilter filter)
|
|
{
|
|
Filters.Add(filter);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="filter"></param>
|
|
public static void RemoveFilter(IMQFilter filter)
|
|
{
|
|
if (Filters.Contains(filter))
|
|
{
|
|
Filters.Remove(filter);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static ICollection<IMQFilter> Filters { get; } =
|
|
new System.Collections.ObjectModel.Collection<IMQFilter>();
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="defaultPublisher"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree"></param>
|
|
/// <param name="msgDesc"></param>
|
|
protected static void CheckFiltersAndPublishNoReturn(Action<Message, bool> defaultPublisher, Message msg,
|
|
bool isAutoFree, Recv2ReturnDescription msgDesc)
|
|
{
|
|
var filer = Filters.FirstOrDefault(p => p.Filter(msg, msgDesc));
|
|
if (filer != null)
|
|
{
|
|
filer.HandleMessage(msg, msgDesc);
|
|
MessagePool.PutMessage(ref msg);
|
|
}
|
|
else
|
|
{
|
|
defaultPublisher(msg, isAutoFree);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="defaultPublisher"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree"></param>
|
|
/// <param name="msgDesc"></param>
|
|
protected static void CheckFiltersCallbackAndPublishNoReturn(Action<Message, bool> defaultPublisher,
|
|
Message msg, bool isAutoFree, Recv2ReturnDescription msgDesc)
|
|
{
|
|
var filer = Filters.FirstOrDefault(p => p.FilterCallback(msg));
|
|
if (filer != null)
|
|
{
|
|
filer.HandleCallbackMessage(msg);
|
|
MessagePool.PutMessage(ref msg);
|
|
}
|
|
else
|
|
{
|
|
defaultPublisher(msg, isAutoFree);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="defaultPublisher"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="isAutoFree"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
protected static T CheckFiltersAndPublish<T>(Func<Message, bool, T> defaultPublisher, Message msg,
|
|
bool isAutoFree, Recv2ReturnDescription msgDesc)
|
|
{
|
|
var filer = Filters.FirstOrDefault(p => p.Filter(msg, msgDesc));
|
|
if (filer != null)
|
|
{
|
|
var ret = filer.HandleMessage(msg, msgDesc);
|
|
if (ret is T value)
|
|
{
|
|
MessagePool.PutMessage(ref msg);
|
|
return value;
|
|
}
|
|
|
|
throw new Exception(
|
|
$"消息过滤器: {filer.Name} 返回值类型无效, 期待类型:{typeof(T)}, 当前类型: {ret?.GetType()}, returnResult: {msgDesc}");
|
|
}
|
|
else
|
|
{
|
|
return defaultPublisher(msg, isAutoFree);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="defaultPublisher"></param>
|
|
/// <param name="msg"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
protected static T CheckFiltersAndCall<T>(Func<T> defaultPublisher, string msg, Recv2ReturnDescription msgDesc)
|
|
{
|
|
var filer = Filters.FirstOrDefault(p => p.CallFilter(msg, msgDesc));
|
|
if (filer != null)
|
|
{
|
|
var ret = filer.HandleCallMessage(msg, msgDesc);
|
|
if (ret is T value)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
throw new Exception(
|
|
$"消息过滤器: {filer.Name} 返回值类型无效, 期待类型:{typeof(T)}, 当前类型: {ret?.GetType()}, returnResult: {msgDesc}");
|
|
}
|
|
else
|
|
{
|
|
return defaultPublisher();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 外发到rabbit消息的过滤器
|
|
/// </summary>
|
|
public interface IMQFilter
|
|
{
|
|
/// <summary>
|
|
/// 过滤器名称
|
|
/// </summary>
|
|
string Name { get; }
|
|
|
|
/// <summary>
|
|
/// 检查此消息是否符合过滤条件
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
bool Filter(Message message, Recv2ReturnDescription msgDesc);
|
|
|
|
/// <summary>
|
|
/// FilterCallback
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
bool FilterCallback(Message message);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
void HandleCallbackMessage(Message message);
|
|
|
|
/// <summary>
|
|
/// 处理此消息
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
object HandleMessage(Message message, Recv2ReturnDescription msgDesc);
|
|
|
|
/// <summary>
|
|
/// 检查RPC Call 消息是否符合过滤条件
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
bool CallFilter(string msg, Recv2ReturnDescription msgDesc);
|
|
|
|
/// <summary>
|
|
/// 处理 RPC Call 消息
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <param name="msgDesc"></param>
|
|
/// <returns></returns>
|
|
object HandleCallMessage(string msg, Recv2ReturnDescription msgDesc);
|
|
}
|
|
|
|
/// <summary>
|
|
/// ReturnResult
|
|
/// </summary>
|
|
public enum Recv2ReturnDescription : byte
|
|
{
|
|
/// <summary>
|
|
/// EveryOne, 无返回
|
|
/// </summary>
|
|
EveryOne_Void = 1,
|
|
|
|
/// <summary>
|
|
/// EveryOne, 返回 bool
|
|
/// </summary>
|
|
EveryOne_Bool = 2,
|
|
|
|
/// <summary>
|
|
/// EveryOne, 返回 string
|
|
/// </summary>
|
|
EveryOne_String = 3,
|
|
|
|
/// <summary>
|
|
/// CallBack
|
|
/// </summary>
|
|
CallBack = 10,
|
|
|
|
/// <summary>
|
|
/// All, 无返回
|
|
/// </summary>
|
|
All_Void = 20,
|
|
|
|
/// <summary>
|
|
/// All, 返回 bool
|
|
/// </summary>
|
|
All_Bool = 21,
|
|
|
|
/// <summary>
|
|
/// One 无返回
|
|
/// </summary>
|
|
One_Void = 30,
|
|
|
|
/// <summary>
|
|
/// One, 返回 bool
|
|
/// </summary>
|
|
One_Bool = 31,
|
|
|
|
/// <summary>
|
|
/// Call EveryOne, 返回 string
|
|
/// </summary>
|
|
Call_EveryOne_String = 40,
|
|
|
|
/// <summary>
|
|
/// Call One, 返回 string
|
|
/// </summary>
|
|
Call_One_String = 41,
|
|
}
|
|
} |