2 {
3 // 轉換消息
4 NetMessageCaptureRecievedMsg(NetMessagemsg); // 在交給處理器之前
5 NetMessageCaptureBeforeSendMsg(NetMessagemsg); // 在發送出去之前
6
7 bool Enabled{ get ; set ;} // 是否啟用本Hook
8 }
通過 INetMessageHook 接口可以看到,當消息進入系統時回被 CaptureRecievedMsg 方法截獲(比如,進行解密處理),當把消息發送到網絡之前,將被 CaptureBeforeSendMsg 方法截獲(比如,進行加密處理)。
如果有多個
INetMessageHook
,則可以形成一個
HookList
,消息經過
HookList
時,分別按順序被每個
INetMessageHook
處理,
ESFramework
中的
HookList
的參考實現是
EsbNetMessageHook
,并且它也實現了
INetMessageHook
接口,這樣就可以把一個
Hook
鏈當作一個
Hook
了。
其源碼如下:

需要特別注意的是, HookList 的實現中,逐個調用 Hook 的 CaptureRecievedMsg 方法的順序必須與逐個調用 CaptureBeforeSendMsg 方法的順序相反,這就是為什么 EsbNetMessageHook 實現 CaptureBeforeSendMsg 方法時,出現下列代碼的原因:
為了說明為什么需要顛倒
Hook
鏈的情況,可以舉個例子,假設有一個“原始消息”從系統
1
發送到系統
2
,其間經過了兩個
Hook
,一個加密
Hook
,一個是壓縮
Hook
,則可表示如下:
系統
1
=》原始消息=》加密=》壓縮=》發送
系統
2
=》接收消息=》解壓縮=》解密=》原始消息
還要提醒的是,在具體的
Hook
實現中,截獲處理經常改變
Body
的大小,如果
Body
的大小真的發生了變化,一定要更新消息頭(
IMessageHeader
)中的
MessageBodyLength
字段。
通常,采用Hook時,服務端與客戶端是對稱的,所以你可以把所有的Hook實現放在一個Dll中,這樣服務端和客戶端可以共同使用這個Hook Dll了。
由于對網絡消息進行壓縮是常見的需求,所以我把
BaseZipHook
納入到了
ESFramework
中,并且,這也是
IMessageHeader
存在
ZipMe
屬性的原因。
ZipMe
屬性用于通知
BaseZipHook
是否對接收到的本條消息進行解壓縮,是否在發送本消息之前進行壓縮。
BaseZipHook
實現如下:

BaseZipHook 是一個抽象類,具體實現的壓縮算法由派生類通過覆寫 Zip 和 Unzip 方法提供。如果要實現一個具體的 ZipHook ,你可以從 BaseZipHook 繼承,并采用 ZipHelper 提供的壓縮 / 解壓縮功能。
到現在為止,我們已經討論了關于消息的比較多的內容了,但還有一個非常重要的組件沒有講到,那就是消息分派器
ITcpStreamDispatcher
,消息分派器直接與
Tcp
組件或
Udp
組件聯系,并且所有消息的進出都要經過
ITcpStreamDispatcher
,所以分派器是一個對消息進行
Hook
的理想位置,并且消息分派器會把具體的消息分派到對應的消息處理器上。欲知道
ITcpStreamDispatcher
的原理與實現,請繼續關注下文:
ESFramework
介紹之(
5
)
――
消息分派器
ITcpStreamDispatcher
上一篇:
ESFramework介紹之(3)――消息處理器和處理器工廠
轉到:
ESFramework 可復用的通信框架(序)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
