反应器组件 ACE_Reactor
反應(yīng)器的基本原理是:
?針對(duì)關(guān)心的某個(gè)事件寫一個(gè)事件處理器(event_handler). 將該事件處理器登記到反應(yīng)器中(同時(shí)指明關(guān)心的事件).?
?然后反應(yīng)器會(huì)自動(dòng)檢測(cè)事件的發(fā)生. 并調(diào)用預(yù)先登記的事件處理器中的回調(diào)函數(shù).?
所以ACE Reactor 框架的責(zé)任:
1、檢測(cè)來(lái)自各種事件源的事件的發(fā)生。
2、將事件多路分離給其預(yù)先登記的事件處理器。
3、分派給處理器所定義的掛鉤方法,從而以一種應(yīng)用定義的方式處理這些事件。
6.2 事件處理器
在ACE中.?反應(yīng)器是ACE_Reactor類的單件對(duì)象(因?yàn)槌绦蛑型ǔV恍枰粋€(gè)反應(yīng)器).?
反應(yīng)器提供了登記/撤銷 事件處理器的接口.?register_handler() /?remove_handler() .
這些接口要求 事件處理器必須是?ACE_Event_Handler?類型的. 所以我們的事件處理器類必須從該類繼承.
在反應(yīng)器需要檢測(cè)某個(gè)I/O句柄上是否有事件時(shí). 需要知道原始句柄. 這樣就需要重寫事件處理器類的get_handle()函數(shù).??
下邊是ACE_Event_Handler 中聲明的鉤子函數(shù):
handle_signal ()??當(dāng)在反應(yīng)器上登記的信號(hào)發(fā)生時(shí). 反應(yīng)器回調(diào)該函數(shù). (不懂)
handle_input ()??當(dāng)來(lái)自I/O設(shè)備的輸入可用時(shí). 反應(yīng)器自動(dòng)回調(diào)該方法.?
handle_exception () ?當(dāng)在反應(yīng)器上登記的異常事件發(fā)生時(shí). (不懂)
handle_timeout ()?當(dāng)在反應(yīng)器上登記的定時(shí)器超時(shí)的時(shí)候. 回調(diào)該方法.
handle_output ()??當(dāng)在IO設(shè)備上的輸出可用時(shí). 回調(diào)該方法.
6.2.1 登記事件處理器
使用 ACE_Reactor 類的?register_handler()?函數(shù). ? 這個(gè)函數(shù)有好幾個(gè)重載形式. ?
該函數(shù)有個(gè)參數(shù)用來(lái)指出感興趣的事件. 它可以是下邊一些常量 (定義在ACE_Event_handler類中):
READ_MASK ?? 句柄上有數(shù)據(jù)可讀時(shí) ? 回調(diào) handle_input()
WRITE_MASK ?? 句柄上可寫時(shí) ? 回調(diào) handle_output()
TIMER_MASK ??回調(diào) handle_close()? 不懂怎么用...
ACCEPT_MASK ?? 有來(lái)自客戶端的新的連接請(qǐng)求時(shí) ? 回調(diào) handle_input()
CONNECT_MASK ? 建立連接時(shí) ? 回調(diào) handle_input()
DONT_CALL ?? 它用在顯式拆除事件處理器的remove_handler()函數(shù)中. 表示拆除前不調(diào)用 handler_close() 函數(shù).
6.2.2 拆除事件處理器
當(dāng)不在需要處理某個(gè)事件時(shí). 需要把對(duì)應(yīng)的事件處理器從反應(yīng)器中拆除.?
有兩種拆除事件處理器的辦法:
?一種是隱式的自動(dòng)拆除.?當(dāng)事件處理器類中的 handle_*** 方法返回的int 小于0 時(shí). 反應(yīng)器會(huì)自動(dòng)調(diào)用事件處理器
??的Handle_close()方法. 并把事件處理器拆除.?
?另一種是顯式拆除. 即調(diào)用 ACE_reactor::remove_handler(). 這也會(huì)調(diào)用事件處理器的handle_close(). 然后拆除.
??不過(guò). 如果你不需要調(diào)用handle_close(). 可以給remove_handler()傳遞參數(shù) ACE_Event_Handler::DONT_CALL .
??具體例子在后邊會(huì)給出.
我在這里創(chuàng)建了一個(gè)簡(jiǎn)單的Event_handler:
class Event_Handler
{
public:
Event_Handler();
virtual ~Event_Handler();
public:
//! 獲取反應(yīng)器
//! @return 反應(yīng)器指針
Reactor* reactor();
//! 設(shè)置反應(yīng)器
//! @param reactor 反應(yīng)器指針
void reactor(Reactor* reactor);
//! 獲取通道id
//! @return 通道id
virtual uint32_t get_id() = 0;
//! 獲取socket句柄
//! @return socket句柄
virtual SOCKET get_handle() = 0;
//! 處理讀
//! @return 處理結(jié)果 0:處理正常, -1: 連接被關(guān)閉, -2:連接異常
virtual int handle_input() = 0;
//! 處理寫
//! @return 處理結(jié)果 0:處理正常, -1: 連接被關(guān)閉, -2:連接異常
virtual int handle_output() = 0;
//! 連接異常
virtual int handle_exception() = 0;
//! 連接關(guān)閉
virtual int handle_close() = 0;
//! 超時(shí)
virtual int handle_timeout() = 0;
//! 提交發(fā)送任務(wù)
//! @param send_task 待發(fā)送的任務(wù)
virtual int post_packet(Net_Packet *send_packet) = 0;
public:
list_head hashitem;
bool read;
bool write;
bool notify_close;
time_t timeout; //<! 超時(shí)的時(shí)間, 0表示沒(méi)有設(shè)置超時(shí)
private:
//! 反應(yīng)器
Reactor *m_reactor;
};
然后創(chuàng)建對(duì)應(yīng)的處理類:
//! @class SOCK_Acceptor
//! @brief tcp監(jiān)聽處理類
class SOCK_Acceptor : public Event_Handler{
...
};
//! @class SOCK_Connector
//! @brief tcp連接處理類
class SOCK_Connector : public Event_Handler{
...
};
//! @class SOCK_Stream
//! @brief tcp通道處理類
class SOCK_Stream : public Event_Handl{
...
};
總結(jié)
以上是生活随笔為你收集整理的反应器组件 ACE_Reactor的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Unity的 UNet组件介绍
- 下一篇: 小谈Online-game服务器端设计(