消息分发机制 当接收到前端发来的消息并解析后 根据包头的消息码来决定分发到哪个模块,以及调用哪个函数

步骤1、需要注册消息码 为了之后找到这个消息码需要干什么事

步骤2、接收到消息并解析后调用根据解析的包头里的消息码到消息管理器里找对应的消息码分发到对应的部件或者函数

步骤3、在对应的部件上面回调写的函数

不多说了直接上代码

// MH_Base.h
#ifndef __MH_Base_h__
#define __MH_Base_h__// 消息处理者基类
class MH_Base
{
public:virtual ~MH_Base() {};virtual void operator()(const void* data, size_t len) = 0;
};/// 全局或者静态函数
class MH_Function : public MH_Base
{
public:typedef void (Function1)(const void* data, size_t len);
public:MH_Function(Function1* func) : _func1(func) {}virtual void operator()( const void* data, size_t len){_func1( data, len);}private:union{Function1* _func1;};
};#endif

MH_Base这个类是处理消息体的基类, MH_Function继承这个类, 之后回调的话要用到这个类里面的数据

//MessageManager.h
#ifndef __MessageMgr_h__
#define __MessageMgr_h__
#include <iostream>
#include "MH_Base.h"/// 所有消息的消息头
struct MessageHeader
{unsigned short     msgKey;                         /// 消息类型unsigned short      msgId;                          /// 消息码
};#define MsgId_Max 100     // 这里先顶一个消息id上限为100 的宏, 正式项目中药根据消息码的增加最大值也跟着增加
class MessageManager
{
public:MessageManager();~MessageManager();public:virtual bool init();virtual void unint();public://--消息void regMessageHandler(unsigned long msgId, MH_Base* mh);void setMessageHandlerEnable(unsigned long msgId, bool setting);virtual bool hasMessageHandler(unsigned long msgId) const;virtual void onMessage(const MessageHeader& hdr, const void* data, size_t len);
protected:MH_Base*          m_msgHandler[MsgId_Max];            // 消息处理函数unsigned char      m_msgHandlerEnable[MsgId_Max];      //是否有效(1有效, 0无效)unsigned char       m_msgHandlerFilter[MsgId_Max];      //是否过滤(1过滤,0不过滤)
};#endif
// MessageManager.cpp
#include "MessageManager.h"MessageManager::MessageManager()
{memset(m_msgHandler, 0, sizeof(m_msgHandler));memset(m_msgHandlerEnable, 1, sizeof(m_msgHandlerEnable));memset(m_msgHandlerFilter, 0, sizeof(m_msgHandlerFilter));
}MessageManager::~MessageManager()
{}bool MessageManager::init()
{// 各个模块注册的时候在这里添加// 例如商城模块  这里我用的是静态函数的借口, 以后想注册商城相关的消息就在regMsgHandler函数里注册了。//ShopMessage::regMsgHandler();  return true;
}void MessageManager::unint()
{for (int i = 0; i < MsgId_Max; ++i ){if ( NULL != m_msgHandler[i]){delete m_msgHandler[i];m_msgHandler[i] = NULL;}}
}void MessageManager::regMessageHandler(unsigned long msgId, MH_Base* mh)
{if (msgId >= MsgId_Max)return;if (m_msgHandler[msgId] != NULL){// 此处警告一下, 这个消息码已经注册过了//ErrorLn(" msgId=" << msgId << " had register..");}m_msgHandler[msgId] = mh;
}void MessageManager::setMessageHandlerEnable(unsigned long msgId, bool setting)
{if (msgId >= MsgId_Max)return;m_msgHandlerEnable[msgId] = (setting ? 1 : 0);
}bool MessageManager::hasMessageHandler(unsigned long msgId) const
{return (msgId < MsgId_Max && m_msgHandler[msgId] != NULL);
}void MessageManager::onMessage(const MessageHeader& hdr, const void* data, size_t len)
{if (hdr.msgId >= MsgId_Max)return;// 消息处理函数MH_Base* pFunc = m_msgHandler[hdr.msgId];if (pFunc == NULL)return;// 该消息被临时禁止,可能存在刷数据操作if (m_msgHandlerEnable[hdr.msgId] == 0){// 需要警告一下//WarningLn(" msgId=" << hdr.msgId << " disable");return;}// 该消息可能被过滤了,不做处理if (m_msgHandlerFilter[hdr.msgId] == 1){// 需要警告一下//WarningLn("msgId = " << hdr.msgId << " filtered");return;}//--消息处理
#ifdef _DEBUG(*pFunc)(data, len);
#elsetry{(*pFunc)(data, len);}catch (...){ErrorLn("msgFun exect Exception, msgId=" << hdr.msgId << ", len=" << nLen);}
#endif
}

这里只要是存储注册的消息码和对应的函数, 并进行分发

// main.cpp
#include <iostream>
#include "MessageManager.h"// 在这里进行测试
// 首先声明 大前提是接收过来的消息已经将包头 和包体解析开了
// 我这里就自己定义一个包头 正常应该是其他端发过来嘚MessageHeader head;MessageManager msg;// 步骤二编写回调函数
void Test_Function(const void* data, size_t len)
{// 此处随便解析一下, 但是正规项目中需要自己严格处理int a = *((int*)data);std::cout << __FUNCTION__ << std::endl;std::cout << a << std::endl;
}void Test_Function2(const void* data, size_t len)
{// 此处随便解析一下, 但是正规项目中需要自己严格处理int a = *((int*)data);std::cout << __FUNCTION__ << std::endl;std::cout << a << std::endl;
}int main()
{// 你可以修改1或者2 来决定调用 Test_Function  还是 Test_Function2head.msgId = 2;// 暂时无用head.msgKey = 1001;// 包体 (包体我没做具体处理)int a = 10;// 步骤1 注册消息码msg.regMessageHandler(1, new MH_Function(&::Test_Function));msg.regMessageHandler(2, new MH_Function(&::Test_Function2));// 步骤3 调用函数, 一般是接收到消息统一在一个地方执行msg.onMessage(head, &a, sizeof(a));system("pause");return 0;
}

在这里说明一下。 我这里把消息解析的步骤都省略了。  直接用结构体代替。 我这里只是进行消息的分发机制

调用上面不是很方便。 实际上可以让MessageManager继承一个单例  以后调用的时候就很方便了的

c++ 消息分发 消息管理相关推荐

  1. (转)MTK 消息分发及窗口管理

    一.总体结构 1. Software Architecture MediaTek Inc . (MTK) 2. MMI Architecture MTK 平台采用的是Pixtel Communicat ...

  2. 深入解析Windows窗口创建和消息分发

    Windows GUI采用基于事件驱动的编程模型,事实上几乎所有的界面库都是这样做的.在纯粹的Window32 SDK编程时代,人们还可以搞懂整个Windows窗体创建和消息的流通过程,但是在现在各种 ...

  3. delphi VCL研究之消息分发机制(转)

    原文来源,http://blog.csdn.net/sushengmiyan/article/details/8635550 1.VCL 概貌 先看一下VCL类图的主要分支,如图4.1所示. 在图中可 ...

  4. kafka 消息分发机制、分区和副本机制

    一.消息分发机制 1.1 kafka 消息分发策略 消息是 kafka 中最基本的数据单元,在 kafka 中,一条消息由key.value两部分构成,在发送一条消息 时,我们可以指定这个key,那么 ...

  5. 【Android 异步操作】Handler 机制 ( Android 提供的 Handler 源码解析 | Handler 构造与消息分发 | MessageQueue 消息队列相关方法 )

    文章目录 一.Handler 构造函数 二.Handler 消息分发 三.MessageQueue 消息队列相关函数 一.Handler 构造函数 一般使用 Handler 时 , 调用 Handle ...

  6. 【Android】Looper消息分发(msg.target.dispatchMessage), Handler消息处理(消息回调/外部回调/自身回调)

    分发消息 for (;;) {     Message msg = queue.next(); // might block msg.target.dispatchMessage(msg); msg. ...

  7. 扩展WCF的消息分发行为

    使用消息分发检查器IDispatchMessageInspector.服务器行为IServiceBehavior.端点行为IEndpointBehavior扩展WCF的消息分发行为 Extend WC ...

  8. 消息分发的同步均衡策略

    2019独角兽企业重金招聘Python工程师标准>>> TimeTunnel在做消息分发时有这样一个场景: A类消息需要做实时分析, 且量很大, 故它的消费者不会只是一台机器, 而是 ...

  9. 轻松搞定RabbitMQ(二)——工作队列之消息分发机制

    上一篇博文中简单介绍了一下RabbitMQ的基础知识,并写了一个经典语言入门程序--HelloWorld.本篇博文中我们将会创建一个工作队列用来在工作者(consumer)间分发耗时任务.同样是翻译的 ...

最新文章

  1. npoi上传xlsx文件,并读取数据
  2. 虚拟化部署之Hyper-V简介
  3. c语言程序设计文件操作,c语言程序设计文件操作方法示例(CreateFile和fopen)
  4. putty 配置导出
  5. 文本比较算法Ⅴ——回顾贴,对前面几篇文章的回顾与质疑
  6. 【Python】青少年蓝桥杯_每日一题_7.27_邮箱密码
  7. 剑指offer:栈的压入、弹出序列
  8. 移动端 c++ 开发_这 10 点值得移动端开发重点学习
  9. NHibernate学习笔记(二):one-to-one关系映射
  10. 什么的SIT测试?什么是UAT测试?
  11. RSG.CFS.v8.0.2 1CD(综合性通用冷弯型钢构件设计工具)
  12. ML笔记 - 自然语言处理常用技术
  13. 功能测试 性能测试 可用性_6种可改善软件的可用性测试方法
  14. N-gram模型详解
  15. 认识netlogon服务
  16. NC344 Z字形输出字符串
  17. ideagit更新一个文件_IDEA 配置 Git,GitHub, 获取项目, 更新项目 (Windows 版本)
  18. php fopen 指定路径,fopen 系统找不到指定路径 PHP文件包含详细讲述
  19. leetcode:6080. 使数组按非递减顺序排列【单调栈 + 合并】
  20. 基于Rsoft的偏心单模光纤数值仿真

热门文章

  1. 博客转移至 http://sunhs.me
  2. Java实现 LeetCode 93 复原IP地址
  3. Android获取设备号SSAID (Android ID) 和 IMEI
  4. 高中计算机兴趣班一般学什么内容,高中主要学什么课程 有哪些科目
  5. 通过SSH终端管理ESXI虚拟机
  6. 如何删除我们的应用在 AppStore 中的负面评论
  7. Protect the self: defense mechanisms in action
  8. pdf怎么合并成一个pdf?电脑怎么把多个pdf文件合并成一个pdf?
  9. 数字芯片设计中的时钟分频电路,你了解多少?
  10. VSCode已经设置过为中文但变成英文的解决办法