事件处理模式之Reactor(一)
写过大中型网络服务器的朋友相信对事件处理模型(有时也叫事件触发模型)不陌生。今天要讲的Reactor就是在事件处理模型中用的比较多的一种设计模式。请大家先看下面的图,有个初步的印象:在上图中,可以看到主要有以下四种角色:
1. Reactor:
Reactor是Reactor模式中最为关键的角色,它是该模式最终向用户提供接口的类。用户可以向Reactor中注册 EventHandler(3),然后Reactor在“反应(react)”的时候,发现用户注册的fd上有事件发生,就会回调用户的事件处理函数。下 面是一个简单的设计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Reactor { public: /// 构造函数 Reactor(); /// 析构函数 ~Reactor(); /// 向reactor中注册关注事件evt的handler(可重入) /// @param handler 要注册的事件处理器 /// @param evt 要关注的事件 /// @retval 0 注册成功 /// @retval -1 注册出错 int RegisterHandler(EventHandler * handler, event_t evt); /// 从reactor中移除handler /// @param handler 要移除的事件处理器 /// @retval 0 移除成功 /// @retval -1 移除出错 int RemoveHandler(EventHandler * handler); /// 处理事件,回调注册的handler中相应的事件处理函数 /// @param timeout 超时时间(毫秒) void HandleEvents(int timeout = 0); private: ReactorImplementation * m_reactor_impl; ///< reactor的实现类 }; |
SynchrousEventDemultiplexer也是Reactor中一个比较重要的角色,它是Reactor用来检测用户注册的fd上发生的事 件的利器,通过过Reactor得知了哪些fd上发什么了什么样的事件,然后以些为依据,来多路分发事件,回调用户的事件处理函数。下面是一个简单的设 计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class EventDemultiplexer { public: /// 获取有事件发生的所有句柄以及所发生的事件 /// @param events 获取的事件 /// @param timeout 超时时间 /// @retval 0 没有发生事件的句柄(超时) /// @retval 大于0 发生事件的句柄个数 /// @retval 小于0 发生错误 virtual int WaitEvents(std::map<handle_t , event_t> * events, int timeout = 0) = 0; /// 设置句柄handle关注evt事件 /// @retval 0 设置成功 /// @retval 小于0 设置出错 virtual int RequestEvent(handle_t handle, event_t evt) = 0; /// 撤销句柄handle对事件evt的关注 /// @retval 0 撤销成功 /// @retval 小于0 撤销出错 virtual int UnrequestEvent(handle_t handle, event_t evt) = 0; }; </handle_t> |
EventHander是用户和Reactor打交道的工具,用户通过向Reactor注册自己的EventHandler,可以告知Reactor在特定事件发生的时候该帮我做些什么。下面是一个简单的设计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class EventHandler { public: /// 获取该handler所对应的句柄 virtual handle_t GetHandle() = 0; /// 处理读事件的回调函数 virtual void HandleRead() {} /// 处理写事件的回调函数 virtual void HandleWrite() {} /// 处理出错事件的回调函数 virtual void HandleError() {} protected: /// 构造函数,只能子类调 EventHandler() {} /// 析构函数,只能子类调 virtual ~EventHandler() {} }; |
ConcreteEventHandler是EventHandler的子类,EventHandler是Reactor所用来规定接口的基类,用户自己的事件处理器都必须从EventHandler继承。
以上简单介绍了一下Reactor模式,最近我自己也在业余时间写了一个可以在windows/linux平台上运行的Reactor库,地址是:http://code.google.com/p/xiao5geproject/source/browse/trunk/reactor/,目前刚刚完成了库的编码,后面抽空我会加上相应的例子,以及单元测试,希望能够对写网络服务器的朋友有所帮助。
-----------------------------------------------------
没有评论:
发表评论