2008年7月的一個週末,突發熱忱,對剛出了M3版本的MINA2起了興趣。下載了原碼以及一部分資料進行研學。當時,做了一部分筆記。但是由於工作等各種原因一年多沒有繼續。正直2010年新年新春之際,於家中整理當時的筆記。準備後續慢慢整理出來。
當時的nio網絡框架並不多,除了MINA2以外還有國內著名的Cindy。兩個框架都作了研學,但是Cindy由於代碼註釋少、以及資料缺乏,作者也消失良久等原因,所以並沒有作爲重點學習目標。
經過3天對MINA2代碼研讀,發現的核心部分從來沒有一篇doc能夠說明清除(至少當時沒有看到),而大部分都停留在使用IoHanlder以及IoFilter等外部擴展上。而我將以NIO的網絡部分爲切入點來介紹其真實的核心部分。
整個筆記會分爲幾部分進行說明:
2. IoAcceptor與IoConnector類族 (IoService)
1 IoAcceptor類族
IoAcceptor類族表示接受socket連接並驅動IoProcessor的實體。概念上IoAcceptor與IoConnector形成IoService的功能,即表示NIO的所有服務。
其類族中,NET相關的類封裝了Selector以及ServerSocketChannel,完成註冊ServerSocketChannel到Selector並接受新到的SocketChannel。
NET相關主要包括如下接口與類:
- AbstractIoAcceptor
- AbstractPollingIoAcceptor
- NioSocketAcceptor
其中AbstractPollingIoAcceptor類實現了核心的流轉功能。NioSocketAcceptor實現了具體的網絡部分。
AbstractPollingIoAcceptor主要封裝了一個Worker 線程程序以及registerQueue、cancalQueue。Worker程序完成Java nio底層的selector的select()行爲操作。而具體的selector封裝在NioSocketAcceptor中。
AbstractPollingIoAcceptor的兩個Queue如下:
registerQueue是存放ServerSocketChannel的queue。Accptor進行偵聽時生成ServerSocketChannel放入其中。Worker循環程序不斷將其取出並註冊到selector中。
cancelQueue是存放ServerSocketChannel的queue。Worker循環程序不斷將其取出並關閉釋放該ServerSocketChannel。
AbstractPollingIoProcessor的Worker核心代碼如下:
這個是一個典型的java nio selector 循環。
- select()用於等待OP_ACCEPT事件。
- registerHandles()調用主要完成從registerQueue取出SSC並註冊到selector。
- processHandles(selectedHandles())主要完成生成新的IoSession對象並將其推送到IoProcessor。
- unregisterHandles()主要是取出cancelQueue中的SSC,然後關閉。
2 IoConnector類族
與IoAccptor類族提供服務端(被動)功能類似,客戶端(主動)部分由IoConnector類族提供功能。其實現方式也與IoAcceptor如出一轍。
其類族中,NET相關的IoConnector類族表示主動發起socket連接並驅動一個IoProcessor對象的實體。概念上IoAcceptor與IoConnector形成IoService的功能,即表示NIO的所有服務。
該類族主要包括以下接口和類:
- AbstractIoConnector
- AbstractPollingIoConnector
- NioSocketConnector
其中AbstractPollingIoConnector是流轉功能的核心類。其中分裝了一個selector用以註冊“CONNECT動作”。當完成連接時將IoSession推送到關聯的IoProcessor 對象中進行下一步處理。
AbstractPollingIoConnector內部有如下Queue:
AbstractPollingIoConnector中worker線程的核心程序如下:
與Acceptor類似核心部分就是一個select()方法的循環處理。通過兩個Queue進行流轉。