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村粗
  }
时间: 2024-10-06 00:39:06

muduo Dispatcher消息分发器 通过多态和模板进行向上类型转换的相关文章

Android中的观察者模式:消息分发器(MessageDispatcher)

这个功能是在公司项目需求的时候写出来,本来是基础命令字模式的,但是个人喜欢对象,所有后来在一个小项目中使用时,改成了基于对象模式. 首先,是一个接口,我们称之为监听器: [html] view plaincopyprint? /** * * @author poet * */ public interface MessageObserver<T> { void onMessage(T t); } 这里使用的是泛型,泛型<T>除了作为实际监听的对象类型,也作为监听器管理的key,届时

Java任务分发器

一.前言说明 任务分发器是相对于RabbitMQ消息处理的一种简化,在项目底层不依赖其他服务时可以使用该方案,特点是随项目分布式部署时以服务器性能决定处理速度,简单.高效.安全.可扩展性等. 实现原理比较简单,使用SimpleAsyncTaskExecutor随项目启动时初始化异步调度的任务,通过配置的异步调度任务创建守护进程,依赖守护进程来初始化ExecutorService线程池和BlockingQueue阻塞队列,以守护进程的线程从数据库读取待处理数据放入队列,线程池创建线程作为消费者去读

谈一下信号分发器的作用及实现方法

信号分发器在很多游戏项目中都有使用,是一种典型的观察者模式.在游戏编程中,客户端的绘制往往需要靠逻辑数据来驱动,绘制通过监听信号等待逻辑的通知.当然了,逻辑模块跟逻辑模块相互之间的通知也可以使用信号.这种编程模式能够简化模块之间的通信问题,不需要引用烦人的指针调用,导致指针满屏飞的情况.C++恶心的地方就是在大型项目中,指针相当多. 那边,实现一个信号分发器需要哪些功能呢?我们知道,所谓的信号通知,无非就是函数调用.监听一个信号,其本质上就是绑定一个指针,这个问题的难点在于函数指针是各式各样的,

Cocos2d-x 3.0 屏幕触摸及消息分发机制

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 题外话: 唉. 开学了!    好烦. 这就已经大三了, 两年前的这时候,我还是懵懂的大一小学弟, 两年后.就要奔上社会就业了. 光阴似箭.日月如梭呀~ 正文: 好久没做cocos2d-x了,这次练习一下.屏幕触摸及消息分发机制. 这里,我用的是cocos2d-

Yarn源码分析之事件异步分发器AsyncDispatcher

AsyncDispatcher是Yarn中事件异步分发器,它是ResourceManager中的一个基于阻塞队列的分发或者调度事件的组件,其在一个特定的单线程中分派事件,交给AsyncDispatcher中之前注册的针对该事件所属事件类型的事件处理器EventHandler来处理.每个事件类型类可能会有多个处理渠道,即多个事件处理器,可以使用一个线程池调度事件.在Yarn的主节点ResourceManager中,就有一个Dispatcher类型的成员变量rmDispatcher,定义如下: pr

SpringMVC核心分发器DispatcherServlet分析[附带源码分析]

SpringMVC核心分发器DispatcherServlet分析[附带源码分析] 目录 前言 DispatcherServlet初始化过程 DispatcherServlet处理请求过程 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html 本文将分析SpringMVC的核心分发器Dispa

SpringMVC核心分发器DispatcherServlet分析

本文将分析SpringMVC的核心分发器DispatcherServlet的初始化过程以及处理请求的过程,让读者了解这个入口Servlet的作用. DispatcherServlet初始化过程 在分析DispatcherServlet之前,我们先看下DispatcherServlet的继承关系. HttpSerlvetBean继承自HttpServlet. HttpServletBean覆写了init方法,对初始化过程做了一些处理. 我们来看下init方法到底做了什么: <servlet> &

openfire开发(四)消息拦截器

大家好,我是LD,今天给大家介绍openfire的消息拦截器.通常,我们在开发插件的过程中会有一种需求,需要对客户端发送的消息来做一些我们自己的处理,比如保存数据等等.这里我们就会使用到拦截器, 在openfire中,自定义拦截器需要实现PacketInterceptor接口.下面我们写一个简单的拦截器来介绍一下. import org.jivesoftware.openfire.interceptor.PacketInterceptor; import org.jivesoftware.ope

jQuery源码分析系列(33) : AJAX中的前置过滤器和请求分发器

jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求,分别是: 1.前置过滤器 jQuery. ajaxPrefilter 2.请求分发器 jQuery. ajaxTransport, 3.类型转换器 ajaxConvert 源码结构: jQuery.extend({ /** * 前置过滤器 * @type {[type]} */ ajaxPrefilter: addToPrefiltersOrTransports(prefilters), /** * 请求分发器 *