/* * 由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 : 提示玩家网络故障,踢出玩家所在的游戏 * * * * */ /// /// 消息管理 工厂 /// public abstract class IGlobalFactory { /// /// 创建消息管理 /// public abstract void CreateGlobalMQ(); } /// /// rabbit消息投递管理类 /// public class GlobalMQ : IGlobalMQ { /// /// 消息管理工厂 /// public class Factory : IGlobalFactory { /// /// 创建消息管理类 /// public override void CreateGlobalMQ() { if (instance == null) instance = new GlobalMQ(); } } /// /// rabbit消息投递管理类单例 /// public static GlobalMQ instance { get; protected set; } /// /// 失败原因的 key 消息未发送成功(502) 消息未被路由(503) 消息被扔弃(504) /// public const string failCode = "failCode"; /// /// 应该由谁来处理这个未被路由或被扔弃的包 /// public const string doFailKey = "doFail"; /// /// 应该由哪个节点来处理扔弃的包 /// public const string doFailNodeNum = "doFailNodeNum"; /// /// 处理失败的标记-有标记的才会处理,没有的会被扔弃 /// public const string failTagKey = "failTag"; /// /// 发送成功要做的事 /// public const string successTagKey = "successTag"; /// /// 构造 /// protected GlobalMQ() { } /// /// 消息管理 /// protected RabbitManager rabbit { get; private set; } /// /// rpc客户端 /// public RpcClient rpcClient { get; private set; } /// /// /// /// public int GetNoAckCount() { if (rabbit == null) return 0; return rabbit.NoAckCount; } /// /// 发送完成事件 /// /// public virtual bool SendOK(Message msg) { return true; } /// /// 发送失败 /// /// 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; } } /// /// 链接阻塞 /// public void ConnectionBlocked() { //if (rabbit == null) // return; //rabbit.ConnectionBlocked(); } /// /// 解除链接阻塞 /// public void ConnectionUnBlocked() { //if (rabbit == null) // return; //rabbit.ConnectionUnBlocked(); } /// /// 发送消息 /// /// 消息 /// 是否自动释放 public virtual void SendMessage(Message msg, bool isAutoFree) { //CheckFiltersAndPublishNoReturn(rabbit.BasicPublish, msg, isAutoFree, Recv2ReturnDescription.One_Void);// rabbit.BasicPublish(msg, isAutoFree); } /// /// 发送消息并要得到发送结果 /// /// ///是否自动释放 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; /// /// rabbit消息管理启动 /// /// rabbit配置 /// 模块 /// 是否删除已存在的路由,大升级要使用到,路由规则已改 /// 启动成功还是失败 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; } /// /// 添加配置 /// /// 配置 /// 当前模块 /// 是否声明前先删除模块 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; } /// /// 是否开启接收消息日志 /// public static bool openMsgLog; /// /// 接收到消息 /// /// 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); } } /// /// 未被路由的消息 事件过来的 /// /// 消息 protected void NotRoutingOk(Message msg) { return; DoFail(msg, 503); } /// /// 分发处理失败的消息 /// /// /// 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()); } } /// /// 发送结果 事件过来的 /// /// 消息 protected void SendResult(Message msg) { if (msg.success) { //发送成功 if (msg.userData == null || !msg.userData.ContainsKey(successTagKey)) { //没有标记 不处理 return; } SendOK(msg); } else { //发送失败 DoFail(msg, 502); } } /// /// 单独的消费者 /// private Consumer exclusiveConsumer; /// /// 共享的消费者 /// private Consumer sharedConsumer; /// /// 处理错误消息的消费者 /// private Consumer doFailConsumer; /// /// 过期的消息队列 /// private const string exipreQueue = "expired"; /// /// 创建消费者 /// 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); } /// /// 添加错误消息的消费者 /// 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); } /// /// 移出处理失败消息的消费者 /// public void RemoveFailConsumer() { if (doFailConsumer != null) rabbit.RemoveConsumer(doFailConsumer); doFailConsumer = null; } /// /// 关闭模块 /// public void Close() { if (rabbit == null) return; rabbit.Close(); } /// /// 等待处理的消息 /// private readonly ConcurrentQueue _waitBeMessages = new ConcurrentQueue(); public int GteMessageCnt() { return _waitBeMessages.Count; } /// /// 拿一条消息 /// /// public WaitBeMsg GetMessage() { if (_waitBeMessages.Count > 0 && _waitBeMessages.TryDequeue(out WaitBeMsg msg)) { return msg; } return null; } /// /// 添加消息 /// /// public void AddMessage(Message msg) { WaitBeMsg tmp = WaitBeMsgPool.GetWaiteBeMsg(msg); _waitBeMessages.Enqueue(tmp); } /// /// 添加消息 /// /// public void AddMessage(WaitBeMsg msg) { _waitBeMessages.Enqueue(msg); } /// /// 创建消息 /// /// json整包 /// 失败标记 /// 谁来处理失败标记 /// 处理失败标记的节点 /// 成功标记 /// /// public static Message CreateMessage(string jsonmessage, string failTag = null, int doFail = -1, int doFailNode = -1, string successTag = null, IDictionary userData = null) { Message msg = MessagePool.GetMessage(); msg.bodystr = jsonmessage; IDictionary dic = new Dictionary(); 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; } /// /// 创建消息 /// /// 包头 /// 包体字符串 /// 发送失败标记 /// 处理失败的模块 /// 处理失败的节点 /// 处理成功的标记 /// /// 消息 public static Message CreateMessage(PackHead head, string otherstring, string failTag = null, int doFail = -1, int doFailNode = -1, string successTag = null, IDictionary userData = null) { head.sendutil = GlobalMQ.instance.myUtile; string message = JsonPack.GetJsonByPack_head(head, otherstring); return CreateMessage(message, failTag, doFail, doFailNode, successTag, userData); } /// /// 创建消息 /// /// 包头 /// 包数据 /// 发送失败的标记 /// 处理失败的模块 /// 处理失败的节点 /// 处理成功的标记 /// /// public static Message CreateMessage(PackHead head, object data = null, string failTag = null, int doFail = -1, int doFailNode = -1, string successTag = null, IDictionary 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 /// /// 投递消息给一个模块 并需要知道投递结果-只能知道是否投递成功,无法知道是否到达队列 /// /// 目标 /// 消息 /// 是否自动释放 /// 持久化 /// true 表示在线并投递成功 false 表示投递失败或者目标不在线 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); } /// /// 投递消息给一个模块 不管结果 /// /// /// /// 是否自动释放 /// 持久化 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); } /// /// 群发给任意模块信息 /// /// /// /// 是否自动释放 /// 持久化 /// 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); } /// /// 群发给任意模块信息 /// /// 目标模块id /// 消息内容 /// 没有绑定该模块则为false 绑定则为true /// 是否自动释放 /// 持久化 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); } /// /// 投递这个模块的所有节点 /// /// /// /// 是否自动释放 /// 持久化 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); } /// /// 投递给这类所有模块 /// /// 目标类模块id /// 消息内容 /// 是否自动释放 /// 持久化 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); } /// /// 投递给所有模块 /// /// /// 是否自动释放 /// 持久化处理 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); } /// /// 投递给所有模块 /// /// /// 是否自动释放 /// 持久化 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); } /// /// RPC Call 方法 /// /// 目标 /// 消息 /// 等待多久 /// 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); } /// /// RPC Call 任意一个模块 /// /// 目标id /// 消息 /// 等待多久 /// 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; } /// /// /// /// /// /// /// /// public string Call(ServerNode target, PackHead head, object data = null, int waitTime = 3000) { string message = JsonPack.GetJsonByPack(head, data); return Call(target, message, waitTime); } /// /// Rpc call /// /// /// /// /// /// public string Call(ServerNode target, PackHead head, string jsonmessage, int waitTime = 3000) { string message = JsonPack.GetJsonByPack_head(head, jsonmessage); return Call(target, message, waitTime); } /// /// call 方法 /// /// /// /// /// /// 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); } /* /// /// /// /// /// /// /// /// public System.Threading.Tasks.Task AsyncCall_EveryOne(int moduleId, ServerHead head, object data = null, int waitTime = 3000) { string message = JsonPack.GetJsonByPack(head, data); return AsyncCall_EveryOne(moduleId, message, waitTime); } */ /* /// /// /// /// /// /// /// public System.Threading.Tasks.Task 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; } */ /// /// call 方法 /// /// /// /// /// /// 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); } /// /// RPC回复 /// /// /// /// public void CallBack(IBasicProperties ibp, object message, IDictionary 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 /// /// AddFilter /// /// public static void AddFilter(IMQFilter filter) { Filters.Add(filter); } /// /// /// /// public static void RemoveFilter(IMQFilter filter) { if (Filters.Contains(filter)) { Filters.Remove(filter); } } /// /// /// public static ICollection Filters { get; } = new System.Collections.ObjectModel.Collection(); /// /// /// /// /// /// /// protected static void CheckFiltersAndPublishNoReturn(Action 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); } } /// /// /// /// /// /// /// protected static void CheckFiltersCallbackAndPublishNoReturn(Action 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); } } /// /// /// /// /// /// /// /// /// protected static T CheckFiltersAndPublish(Func 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); } } /// /// /// /// /// /// /// /// protected static T CheckFiltersAndCall(Func 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(); } } } /// /// 外发到rabbit消息的过滤器 /// public interface IMQFilter { /// /// 过滤器名称 /// string Name { get; } /// /// 检查此消息是否符合过滤条件 /// /// /// /// bool Filter(Message message, Recv2ReturnDescription msgDesc); /// /// FilterCallback /// /// /// bool FilterCallback(Message message); /// /// /// /// /// void HandleCallbackMessage(Message message); /// /// 处理此消息 /// /// /// /// object HandleMessage(Message message, Recv2ReturnDescription msgDesc); /// /// 检查RPC Call 消息是否符合过滤条件 /// /// /// /// bool CallFilter(string msg, Recv2ReturnDescription msgDesc); /// /// 处理 RPC Call 消息 /// /// /// /// object HandleCallMessage(string msg, Recv2ReturnDescription msgDesc); } /// /// ReturnResult /// public enum Recv2ReturnDescription : byte { /// /// EveryOne, 无返回 /// EveryOne_Void = 1, /// /// EveryOne, 返回 bool /// EveryOne_Bool = 2, /// /// EveryOne, 返回 string /// EveryOne_String = 3, /// /// CallBack /// CallBack = 10, /// /// All, 无返回 /// All_Void = 20, /// /// All, 返回 bool /// All_Bool = 21, /// /// One 无返回 /// One_Void = 30, /// /// One, 返回 bool /// One_Bool = 31, /// /// Call EveryOne, 返回 string /// Call_EveryOne_String = 40, /// /// Call One, 返回 string /// Call_One_String = 41, } }