Mina入門

:mina屏蔽了網絡通信的一些細節,對sokcet進行封裝,並且是NIO的一個實現框架,可以幫助我們快速的開發網絡通信,

1.1:mima的工程流程

IOService接口

用戶描述我們的客戶端可服務端接口,其子類是connector和acceptor,分別用於描述我們的客戶端和服務端IOproceser多線程環境來處理我們的連接請求流程   

ioFilter提供數據的過來工作,包括編碼,解碼,日誌等信息的過濾

Hanlder就是我們的業務對象,自定義的hanlder需要實現IOHandlerAcceptor。

 

 

1.2:mina的類結構

 

 

IOService   :描述的是客戶端和服務端連接的描述,常常用戶接受和發送數據

1.2.1:執行過程

:

1.2.2:設計到的類

 NIOSocketAcceptor       通信管理

 IOseeeion :session管理

IoService:這個接口在一個線程上負責套接字的建立,擁有自己的Selector,監聽是否有連接被建立。

IoProcessor:這個接口在另一個線程上,負責檢查是否有數據在通道上讀寫,也就是說它也擁有自己的Selector,這是與我們使用JAVA NIO 編碼時的一個不同之處,通常在JAVA NIO 編碼中,我們都是使用一個Selector,也就是不區分IoService與IoProcessor 兩個功能接口。另外,IoProcessor 負責調用註冊在IoService 上的過濾器,並在過濾器鏈之後調用IoHandler。
IoFilter:這個接口定義一組攔截器,這些攔截器可以包括日誌輸出、黑名單過濾、數據的編碼(write 方向)與解碼(read 方向)等功能,其中數據的encode 與decode是最爲重要的、也是你在使用Mina 時最主要關注的地方。
IoHandler:這個接口負責編寫業務邏輯,也就是接收、發送數據的地方。

 

 

 

 

二:mina的長短連接

長連接:

      客戶端和服務端保持一個長時間連接狀態, 所謂長連接,指在一個TCP連接上可以連續發送多個數據包,在TCP連接保持期間,如果沒有數據包發送,需要雙方發檢測包以維持此連接,一般需要自己做在線維持(不發生RST包和四次揮手)。   

短連接

      短連接是指通信雙方有數據交互時,就建立一個TCP連接,數據發送完成後,則斷開此TCP連接(管理起來比較簡單,存在的連接都是有用的連接,不需要額外的控制手段);

 

 

三:IOService接口介紹

3.1:IOService:

  3.1.1: IOService 實現了網絡通信額客戶端和服務端之間的抽象,用於描述客戶端額子接口IOConnector,用於描述服務端IOAcceptor

 :3.1.2: IOService可以管理我們網絡通信的客戶端和服務端,並且可以管理雙方回話,session同樣可以添加過濾器。

 

 

3.1.3:IOService的類結構

通過擴展子接口和抽象子類達到擴展額目的

 

 

(1.)IoService

這個接口是服務端 IoAcceptor、客戶端 IoConnector 的抽象,提供 IO 服務和管理 IoSession 的功能,它有如下幾個常用的方法:

    1. TransportMetadata  getTransportMetadata()

這個方法獲取傳輸方式的元數據描述信息,也就是底層到底基於什麼的實現,譬如:nio、apr 等。

 

    1. void  addListener(IoServiceListener  listener)

這個方法可以爲 IoService 增加一個監聽器,用於監聽 IoService 的創建、活動、失效、空閒、銷燬,具體可以參考 IoServiceListener 接口中的方法,這爲你參與 IoService 的生命週期提供了機會。

 

    1. void  removeListener(IoServiceListener  listener)這個方法用於移除上面的方法添加的監聽器。

 

    1. void  setHandler(IoHandler  handler)

這個方法用於向 IoService 註冊IoHandler,同時有 getHandler()方法獲取Handler。

 

    1. Map<Long,IoSession>  getManagedSessions()

這個方法獲取 IoService 上管理的所有 IoSession,Map 的 key 是IoSession 的 id。

 

    1. IoSessionConfig  getSessionConfig()

這個方法用於獲取 IoSession 的配置對象,通過 IoSessionConfig 對象可以設置 Socket 連接的一些選項。

 

 

 
   

(2.)IoAcceptor

這個接口是 TCPServer 的接口,主要增加了 void bind()監聽端口、void unbind()解除對套接字的監聽等方法。這裏與傳統的 JAVA 中的 ServerSocket 不同的是 IoAcceptor 可以多次調用 bind()方法(或者在一個方法中傳入多個 SocketAddress 參數)同時監聽多個端口。

 

 

 
   

(3.)IoConnector

這個接口是 TCPClient 的接口, 主要增加了 ConnectFuture connect(SocketAddress remoteAddress,SocketAddress localAddress)方法,用於與 Server 端建立連接,第二個參數如果不傳遞則使用本地的一個隨機端口訪問 Server 端。這個方法是異步執行的,同樣的, 也可以同時連接多個服務端。

 

 

 

(4.)IoSession

這個接口用於表示 Server 端與 Client 端的連接,IoAcceptor.accept()的時候返回實例。這個接口有如下常用的方法:

  1. WriteFuture  write(Object  message)

這個方法用於寫數據,該操作是異步的。

 

  1. CloseFuture  close(boolean  immediately)

這個方法用於關閉 IoSession,該操作也是異步的,參數指定 true 表示立即關閉,否則就在所有的寫操作都 flush 之後再關閉。

 

  1. Object  setAttribute(Object  key,Object  value)

這個方法用於給我們向會話中添加一些屬性,這樣可以在會話過程中都可以使用,類似於HttpSession 的 setAttrbute()方法。IoSession 內部使用同步的 HashMap 存儲你添加的自定義屬性。

 

  1. SocketAddress  getRemoteAddress()這個方法獲取遠端連接的套接字地址。

 

  1. void  suspendWrite()

這個方法用於掛起寫操作,那麼有 void resumeWrite()方法與之配對。對於 read()方法同樣適用。

 

  1. ReadFuture read():

這個方法用於讀取數據, 但默認是不能使用的, 你需要調用 IoSessionConfig 的setUseReadOperation(true)纔可以使用這個異步讀取的方法。一般我們不會用到這個方法, 因爲這個方法的內部實現是將數據保存到一個 BlockingQueue,假如是 Server 端,因爲大量的 Client 端發送的數據在 Server 端都這麼讀取,那麼可能會導致內存泄漏,但對於Client,可能有的時候會比較便利。

 

  1. IoService  getService()

這個方法返回與當前會話對象關聯的 IoService 實例。

 

 

四:自定義過濾器

前面我們看到了 LoggingFilter、ProtocolCodecFilter 兩個過濾器,一個負責日誌輸出, 一個負責數據的編解碼,通過最前面的 Mina 執行流程圖,在 IoProcessor 與IoHandler 之間可以有很多的過濾器,這種設計方式爲你提供可插拔似的擴展功能提供了非常便利的方式,目前的 Apache CXF、Apache Struts2 中的攔截器也都是一樣的設計思路。

Mina 中的 IoFilter 是單例的,這與 CXF、Apache Struts2 沒什麼區別。IoService 實例上會綁定一個 DefaultIoFilterChainBuilder 實例,

DefaultIoFilterChainBuilder 會把使用內部的EntryImpl 類把所有的過濾器按照順序連在一起,組成一個過濾器鏈。

DefaultIoFilterChainBuilder 類如下常用的方法:

  1. void  addFirst(String  name,IoFilter  filter)

這個方法把過濾器添加到過濾器鏈的頭部,頭部就是 IoProcessor 之後的第一個過濾器。同樣的 addLast()方法把過濾器添加到過濾器鏈的尾部。

 

  1. void  addBefore(String  baseName,String  name,IoFilter  filter)

這個方法將過濾器添加到baseName 指定的過濾器的前面,同樣的 addAfter()方法把過濾器添加到 baseName 指定的過濾器的後面。這裏要注意無論是那種添加方法,每個過濾器的名字(參數 name)必須是唯一的。

 

  1. IoFilter  remove(Stirng  name)

這個方法移除指定名稱的過濾器,你也可以調用另一個重載的 remove()方法,指定要移除的 IoFilter 的類型。

 

  1. List<Entry>  getAll()

這個方法返回當前 IoService 上註冊的所有過濾器。

 

默認情況下,過濾器鏈中是空的,也就是getAll()方法返回長度爲 0 的 List,但實際 Mina 內部有兩個隱藏的過濾器:HeadFilter、TailFilter,分別在List 的最開始和最末端,很明顯,TailFilter 在最末端是爲了調用過濾器鏈之後,調用 IoHandler。但這兩個過濾器對你來說是透明的,可以忽略它們的存在。

 

編寫一個過濾器很簡單,你需要實現 IoFilter 接口,如果你只關注某幾個方法,可以繼承IoFilterAdapter 適配器類。IoFilter 接口中主要包含兩類方法,一類是與 IoHandler 中的方法名一致的方法,相當於攔截 IoHandler 中的方法,另一類是 IoFilter 的生命週期回調方法,這些回調方法的執行順序和解釋如下所示:

 

(1.)init()在首次添加到鏈中的時候被調用,但你必須將這個 IoFilter 用 ReferenceCountingFilter 包裝起來,否則 init()方法永遠不會被調用。(2.)onPreAdd()在調用添加到鏈中的方法時被調用,但此時還未真正的加入到鏈。 (3.)onPostAdd()在調用添加到鏈中的方法後被調,如果在這個方法中有異常拋出,則過濾器會立即被移除,同時 destroy()方法也會被調用(前提是使用 ReferenceCountingFilter 包裝)。

(4.)onPreRemove()在從鏈中移除之前調用。 (5.)onPostRemove()在從鏈中移除之後調用。

(6.)destory()在從鏈中移除時被調用,使用方法與init()要求相同。

 

無論是哪個方法,要注意必須在實現時調用參數 nextFilter 的同名方法,否則,過濾器鏈的執行將被中斷,IoHandler 中的同名方法一樣也不會被執行,這就相當於 Servlet 中的Filter 必須調用 filterChain.doFilter(request,response)才能繼續前進是一樣的道理。

   在handler處理之前,需要調用相應的

 

 

 

 

 

 

五:IOSession

這個接口用於表示 Server 端與 Client 端的連接,IoAcceptor.accept()的時候返回實例。這個接口有如下常用的方法:

  1. WriteFuture  write(Object  message)

這個方法用於寫數據,該操作是異步的。

 

  1. CloseFuture  close(boolean  immediately)

這個方法用於關閉 IoSession,該操作也是異步的,參數指定 true 表示立即關閉,否則就在所有的寫操作都 flush 之後再關閉。

 

  1. Object  setAttribute(Object  key,Object  value)

這個方法用於給我們向會話中添加一些屬性,這樣可以在會話過程中都可以使用,類似於HttpSession 的 setAttrbute()方法。IoSession 內部使用同步的 HashMap 存儲你添加的自定義屬性。

 

  1. SocketAddress  getRemoteAddress()這個方法獲取遠端連接的套接字地址。

 

  1. void  suspendWrite()

這個方法用於掛起寫操作,那麼有 void resumeWrite()方法與之配對。對於 read()方法同樣適用。

 

  1. ReadFuture read():

這個方法用於讀取數據, 但默認是不能使用的, 你需要調用 IoSessionConfig 的setUseReadOperation(true)纔可以使用這個異步讀取的方法。一般我們不會用到這個方法, 因爲這個方法的內部實現是將數據保存到一個 BlockingQueue,假如是 Server 端,因爲大量的 Client 端發送的數據在 Server 端都這麼讀取,那麼可能會導致內存泄漏,但對於Client,可能有的時候會比較便利。

 

  1. IoService  getService()

這個方法返回與當前會話對象關聯的 IoService 實例。

 

IoSessionConfig

這個方法用於指定此次會話的配置,它有如下常用的方法:

  1. void  setReadBufferSize(int  size)

這個方法設置讀取緩衝的字節數,但一般不需要調用這個方法,因爲 IoProcessor 會自動調整緩衝的大小。你可以調用 setMinReadBufferSize()、setMaxReadBufferSize()方法,這樣無論 IoProcessor 無論如何自動調整,都會在你指定的區間。

 

  1. void  setIdleTime(IdleStatus  status,int  idleTime)

這個方法設置關聯在通道上的讀、寫或者是讀寫事件在指定時間內未發生,該通道就進入空閒狀態。一旦調用這個方法,則每隔idleTime 都會回調過濾器、IoHandler 中的sessionIdle() 方法。

 

  1. void  setWriteTimeout(int  time)這個方法設置寫操作的超時時間。

 

  1. void  setUseReadOperation(boolean  useReadOperation) 這個方法設置 IoSession 的 read()方法是否可用,默認是 false。

 

 

 

 

 

六:線程模型

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了164 篇原創文章 · 獲贊 56 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章