所谓消息分发(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