首页 > 源码分享, 程序人生 > 事件处理模式之Reactor(一)

事件处理模式之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的实现类
};

2. SynchrousEventDemultiplexer:
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>

3. EventHandler:
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() {}
};

4. ConcreteEventHandler:
ConcreteEventHandler是EventHandler的子类,EventHandler是Reactor所用来规定接口的基类,用户自己的事件处理器都必须从EventHandler继承。

以上简单介绍了一下Reactor模式,最近我自己也在业余时间写了一个可以在windows/linux平台上运行的Reactor库,地址是:http://code.google.com/p/xiao5geproject/source/browse/trunk/reactor/,目前刚刚完成了库的编码,后面抽空我会加上相应的例子,以及单元测试,希望能够对写网络服务器的朋友有所帮助。
—————————————————–
BTW:google code代码显示中文是乱码的朋友,请点右下方”view raw file”查看原始文件,谢谢。

  1. 2011年3月29日23:57 | #1

    SynchrousEventDemultiplexer的作用看的不是很清楚。
    整体概念看懂了,等你的demo啦~

  2. 2011年3月30日00:39 | #2

    Reactor要知道在哪些fd上发生了哪些事件,才能进行”React”,回调对应的事件处理函数,进行事件处理。SynchrousEventDemultiplexer就是Reactor用来获取“哪些fd上发生了什么事件”的东东。@Leon

  3. 2011年4月4日12:05 | #3

    看了博主的文章,比较实在,学习了,希望以后能够有更多的机会和博主交流!

  1. 2011年4月5日23:14 | #1
您必须在 登录 后才能发布评论.