feat: initial commit - HJHA game server full source
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
This commit is contained in:
1359
GlobalSever/MQ/GlobalMQ.cs
Normal file
1359
GlobalSever/MQ/GlobalMQ.cs
Normal file
@ -0,0 +1,1359 @@
|
||||
/*
|
||||
* 由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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user