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

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