muduo Dispatcher消息分发器 通过多态和模板进行向上类型转换
时间:2022-07-26
本文章向大家介绍muduo Dispatcher消息分发器 通过多态和模板进行向上类型转换,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
所谓消息分发(muduo 中,就是接收到buffer之后,额,或者说是 protobuf),在简单的程序设计里面的话,估计就是 type-switch 了,但是这样的话,肯定就不好扩展维护啦。
最后的方法就是,可以根据 type-name 自动去调用相应的方法。
typedef boost::function<void (Message*)> ProtobufMessageCallback;
这个算是一个映射咯。muduo 中采用的是 map<Descriptor*,ProtobufMessageCallback>,使用前,先注册,注册了就有相应的方法可以调用了。
muduo 中就提出了一个要求,要求回调之后,用户不需要自己再做类型转换的事情;
比如
QueryServer::onLogin(Message *){
Login * pL = dynaminc_cast<Login *>(pMsg); //这里就用户要自己调用类型转换
}
//智能指针要用 boost::shared_ptr<DeriveClass> ptrDerive = boost::dynamic_pointer_cast<DeriveClass>(ptrBase);
// 来进行向上类型转换。
于是 muduo 就采用 多态+模板的方法,这样,用户只需要在 dispatcher 中注册相应的具体类型的回调函数就可以了。
typedef boost::shared_ptr<google::protobuf::Message> MessagePtr;
class Callback : boost::noncopyable
{
public:
virtual ~Callback() {};
virtual void onMessage(const muduo::net::TcpConnectionPtr&,
const MessagePtr& message,
muduo::Timestamp) const = 0;
};
template <typename T>
class CallbackT : public Callback
{
#ifndef NDEBUG
BOOST_STATIC_ASSERT((boost::is_base_of<google::protobuf::Message, T>::value));
#endif
public:
typedef boost::function<void (const muduo::net::TcpConnectionPtr&,
const boost::shared_ptr<T>& message,
muduo::Timestamp)> ProtobufMessageTCallback;
CallbackT(const ProtobufMessageTCallback& callback)
: callback_(callback)
{
}
virtual void onMessage(const muduo::net::TcpConnectionPtr& conn,
const MessagePtr& message,
muduo::Timestamp receiveTime) const
{
boost::shared_ptr<T> concrete = muduo::down_pointer_cast<T>(message);//消息类型转换
assert(concrete != NULL);
callback_(conn, concrete, receiveTime);//调用回调
}
private:
ProtobufMessageTCallback callback_;
};
再一个模板注册函数
template<typename T>
void registerMessageCallback(const typename CallbackT<T>::ProtobufMessageTCallback& callback)
{
boost::shared_ptr<CallbackT<T> > pd(new CallbackT<T>(callback));//根据回调生成相应的function
callbacks_[T::descriptor()] = pd;//注册,也就是使用map村粗
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Go语言入门(八)线程安全&锁
- 一天一大 leet(最佳观光组合)难度:中等 DAY-17
- Django环境搭建
- javascript 中的位运算符
- python 操作 redis 的一些例子
- mongoDB(一)生产环境基础实践
- 一天一大 leet(验证回文串)难度:简单 DAY-19
- mongoDB(二)mongoDB副本集实战
- 一天一大 leet(正则表达式匹配)难度:困难 DAY-20
- mongoDB (三) mongoDB分片集群
- mongoDB (四) mongoDB认证
- 一天一大 leet(二叉树中的最大路径和)难度:困难 DAY-21
- 一天一大 leet(把数字翻译成字符串)难度:中等 DAY-9
- 一天一大 leet(模式匹配)难度:中等 DAY-22
- 一天一大 leet(二进制求和)难度:简单 DAY-23