在《與IoFilter相關的幾個類》和《與IoHandler相關的幾個類》兩篇文檔中我們了解了IoFilter和IoHandler的基本用法,以及其相關類的作用和用途。在本文中主要探討IoFilter和IoHandler的主要區別和聯系。
?
在上面的兩篇文檔中都提到了IoFilter和IoHandler都是對服務器或客戶端(IoAcceptor/IoConnector)接收到的數據進行處理。在Mina的官方文檔《The high-performance protocol construction toolkit》給出了IoFilter和IoHandler在Mina數據傳輸中的執行順序,如下圖:
?
上圖顯示了IoService進行數據讀寫時,各主要組件的執行順序:
(1)IoService讀取數據時個組件的執行順序是:IoProcessor-->IoFilter-->IoHandler。
(2)IoService發送數據時的執行數順序:IoHandler-->IoFilter-->IoProcessor。
?
IoProcessor是一個處理線程,它的主要作用是根據當前連接的狀態的變化(創建會話、開啟會話、接收數據、發送數據、發生異常等等),來將數據或事件通知到IoFilter,當IoFilter的相應的方法接收到該狀態的變化信息是會對接收到的數據進行處理,處理完畢后會將該事件轉發到IoHandler中,有IoHandler完成最終的處理。在這里IoProcessor的主要功能是創建資源(創建/分配線程給IoFilter)和數據轉發(轉發到IoFilter),IoFilter對數據進行基本的分類(如編解碼),IoHandler則負責具體的邏輯實現。也就是說IoFilter對接收到的數據包的具體內容不做處理,而是有IoHandler來對所接收到的數據包進行處理,根據數據包的內容向客戶端返回響應的信息。
?
我們以《與IoHandler相關的幾個類》中KFC售貨機的例子來做一個具體的解釋,在該例子中,客戶端需要想服務器發送查詢價格的請求,服務器根據接收到的請求查詢物品的價格,然后將該物品的價格返回到客戶端。客戶端在向服務器發送數據前會有IoFilterr將發送的信息序列化為二進制數據,然后有IoProcess發送出去,簡化如下:
?????? IoHandler發送客戶端數據-->IoFilter進行序列化-->IoProcessor
上面是數據的發送過程,當服務器接收到客戶端的的請求數據后,先有IoProcessor將該數據轉發到IoFilter,IoFilter將對象進行反序列化,反序列化的結果完成后將數據轉發到IoHandler中,過程簡化如下:
?IoProcessor接收客戶度端的數據-->IoFilter進行反序列化-->IoHandler根據請求查詢價格
這樣一個完整的數據請求的過程就完成了。
?
上面簡單介紹了IoFilter和IoHandler在Mina中的作用,前者是數據的轉換層,后者是業務層。但是兩者在很多地方都有相似之處,為了將兩者的區別做更詳細的討論,先給出兩者的結構圖:
?
圖中的IoFilter比IoHandler中多出的一個最重要的方法就是filterWriter(),該方法會在程序調用session.write()的時候觸發,該方法的重要之處就在于它表明了IoFilter和IoHandler的重要區別,即進行IoFilter是數據的收發層,也可以說是一個數據的收發器,而IoHandler則是邏輯層,并不負責數據的收發,如果把IoProcessor說成是底層的數據收發層,則IoFilter則是一個上層的數據收發層。關于IoFilter中on*()的方法的使用和作用請參考幫助文檔,這里不再給出具體的解釋。
?
到此我們就可以明白了IoFilter是一個數據收發和轉化的裝置,而IoHandler則是一個單一的業務處理裝置,你的所有業務邏輯都應該寫在這個類中。如果沒有在IoService中配置IoFilter,那么在IoHandler中接收到的數據是一個ByteBuffer,你需要在你的IoHandler(業務層)中完成數據的轉化,但是這樣就破壞了Mina中各個組件層的關系,這樣你的程序結構就不在清晰,因此建議在使用Mina時將數據的轉化(即二進制與對象之間的轉換放在IoFilter層來處理)。在Mina中必須要配置IoHandler,因為Mina中提供的IoService中的bind方法必須要有一個IoHandler,因此IoHandler不能省略。
?
到這里對于IoFilter和IoHandler的內容已經講述完畢,下面的內容是對我在開發中遇到的一些問題的一些總結,順便也給自己以前的問題寫出答案:
(1)IoHandler和IoHandlerCommand的區別和聯系。
?? IoHandler和IoHandlerCommand是兩個接口,在開發中經常遇到的他們兩個現類分別是IoHandlerAdpater和IoHandlerChain,IoHandlerAdpater的子類ChainedIoHandler和IoHandlerChain結合使用可以實現多個邏輯功能,IoHandlerChain代表IoHandlerCommand)是業務邏輯的處理單元,而ChainedIoHandler(代表Iohandler)則是處理這些邏輯單元的組件。因此它們的區別是:IoHandler是刀俎,而IoHandlerCommand則是魚肉。他們的一般用法如下:
??
IoHandlerChain chain = new IoHandlerChain();// 創建邏輯處理組件
chain.addLast("first", new FistCommand);// 添加邏輯組件單元一
chain.addLast("second", new SecondCommand);// 邏輯組件單元二
ChainedIoHandler chained = new ChainedIoHandler(chain);// 創建邏輯組件執行模塊
chained.messageReceived(session, message);// 當messageReceived觸發該事件
?
(2)IoFilter和IoHandler可以同時使用嗎?
?? IoFilter和IoHandler由于分工不同,因此他們需要同時使用,但是這不是絕對的,在Mina
?? 的IoService中可以不配置IoFilter,但是必須配置IoHandler。但是,這不是提倡的方式,
?? 因為這破壞的mina的分層結構,因此建議在使用Mina的時候同時使用IoFilter和
?? IoHandler。
(3)IoFilter和IoHandlerCommand/IoHandler的區別和聯系。
?
? 這個問題的答案請參考問題(1)和(2)給出的解釋。
(4)IoHandlerAdpater和IoFilterAdpater的區別和聯系。
?? IoHandlerAdpater和IoFilterAdpater一個是業務邏輯層的監聽器,一個數據傳輸層的監
?? 聽器,他們的區別就是IoHandler和IoFilter的區別,這個在上面已經討論清楚了,不在
?? 詳細說明。
(5)IoFilterChainBuilder和ChainedIoHandler的區別和聯系。
???? 關于這個問題的討論會在后續的文檔中給出。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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