Android使用Apach Mina入門讀書(一)

来源:http://www.cnblogs.com/allensong815260/archive/2016/04/27/5440687.html
-Advertisement-
Play Games

最近開發一個項目需要用到Client(Android)透過Socket與Server通訊,網上有看到Apache封裝好的Socket通訊包,初步學習。 內容主要來源於(MINA官方教程(中文版)) 1.網路應用架構: 基於ApacheMINA的網路應用有三個層次,分別是I/O服務、I/O過濾器和I/ ...


最近開發一個項目需要用到Client(Android)透過Socket與Server通訊,網上有看到Apache封裝好的Socket通訊包,初步學習。

內容主要來源於(MINA官方教程(中文版))

1.網路應用架構:

基於ApacheMINA的網路應用有三個層次,分別是I/O服務、I/O過濾器和I/O處理器:
I/O服務:I/O服務用來執行實際的I/O操作。ApacheMINA已經提供了一系列支持不同協議的I/O服務,如TCP/IP、UDP/IP、串口和虛擬機內部的管道等。開發人員也可以實現自己的I/O服務。
I/O過濾器:I/O服務能夠傳輸的是位元組流,而上層應用需要的是特定的對象與數據結構。
   I/O過濾器用來完成這兩者之間的轉換。I/O過濾器的另外一個重要作用是對輸入輸出的數據進行處理,滿足橫切的需求。多個I/O過濾器串聯起來,形成I/O過濾器鏈。
I/O處理器:I/O處理器用來執行具體的業務邏輯。對接收到的消息執行特定的處理。創建一個完整的基於ApacheMINA的網路應用,需要分別構建這三個層次。

2.完成Client代碼初始化四步驟:

    //第一步:創建連接對象:
    SocketConnector connector = new NioSocketConnector();
   
     //第二步:給該連接對象設置處理對象:(IoHandlerAdapter)
    ClientHandler handler = new ClientHandler();
    connector.setHandler(handler);
  

    // 第三步:添加過濾器:
    connector.getFilterChain().addLast("codec",
        new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),
            LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue())));   


    //第四步:綁定即將通信對象:
    connector.connect(new InetSocketAddress("192.168.1.101", 5260));

3. I/O服務(IoService是I/O服務的介面,繼承 IoAcceptor)

I/O服務用來執行真正的I/O操作,以及管理I/O會話。根據所使用的數據傳輸方式的不同,有不同的I/O服務的實現。由於I/O服務執行的是輸入和輸出兩種操作,實際上有兩種具體的子類型。一種稱為“I/O接受器(I/Oacceptor)”,用來接受連接,一般用在伺服器的實現中;另外一種稱為“I/O連接器(I/Oconnector)”,用來發起連接,一般用在客戶端的實現中。

表1.IoService中的重要方法方法說明
setHandler(IoHandlerhandler):設置I/O處理器。該I/O處理器會負責處理該I/O服務所管理的所有I/O會話產生的I/O事件。getFilterChain()獲取I/O過濾器鏈,可以對I/O過濾器進行管理,包括添加和刪除I/O過濾器。
getManagedSessions():獲取該I/O服務所管理的I/O會話。

I/O連接器 Code Example:

SocketConnectorconnector=newNioSocketConnector();

connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
connector.getFilterChain().addLast("logger",newLoggingFilter());

connector.getFilterChain().addLast("protocol",
newProtocolCodecFilter(newTetrisCodecFactory()));
ConnectFutureconnectFuture=connector.connect(newInetSocketAddress(host,port));

connectFuture.awaitUninterruptibly();

4.I/O會話(IoSession)

I/O會話表示一個活動的網路連接,與所使用的傳輸方式無關。I/O會話可以用來存儲用戶自定義的與應用相關的屬性。這些屬性通常用來保存應用的狀態信息,還可以用來在I/O過濾器和I/O處理器之間交換數據。I/O會話在作用上類似於Servlet規範中的HTTP會話。

表2.IoSession中的重要方法方法說明:
close(booleanimmediately):關閉當前連接。如果參數immediately為true的話,連接會等到隊列中所有的數據發送請求都完成之後才關閉;否則的話就立即關閉。
getAttribute(Objectkey):從I/O會話中獲取鍵為key的用戶自定義的屬性。
setAttribute(Objectkey,Objectvalue):將鍵為key,值為value的用戶自定義的屬性存儲到I/O會話中。
removeAttribute(Objectkey):從I/O會話中刪除鍵為key的用戶自定義的屬性。
write(Objectmessage):將消息對象message發送到當前連接的對等體。該方法是非同步的,當消息被真正發送到對等體的時候,IoHandler.messageSent(IoSession,Object)會被調用。如果需要的話,也可以等消息真正發送出去之後再繼續執行後續操作。

這個介面有如下常用的方法:
A. WriteFuture write(Object message):這個方法用於寫數據,該操作是非同步的。
B. CloseFuture close(boolean immediately):這個方法用於關閉IoSession,該操作也是非同步的,參數指定true 表示立即關閉,否則就在所有的寫操作都flush 之後再關閉。
C. Object setAttribute(Object key,Object value):這個方法用於給我們向會話中添加一些屬性,這樣可以在會話過程中都可以使用,類似於HttpSession 的setAttrbute()方法。IoSession 內部使用同步的HashMap 存儲你添加的自定義屬性。

5.I/O過濾器(IoFilterAdapter)

從I/O服務發送過來的所有I/O事件和請求,在到達I/O處理器之前,會先由I/O過濾器鏈中的I/O過濾器進行處理。過濾器可以在很多情況下使用,比如記錄日誌、性能分析、訪問控制、負載均衡和消息轉換等。過濾器非常適合滿足網路應用中各種橫切的非功能性需求。在一個基於ApacheMINA的網路應用中,一般存在多個過濾器。這些過濾器互相串聯,形成鏈條,稱為過濾器鏈。每個過濾器依次對傳入的I/O事件進行處理。當前過濾器完成處理之後,由過濾器鏈中的下一個過濾器繼續處理。當前過濾器也可以不調用下一個過濾器,而提前結束,這樣I/O事件就不會繼續往後傳遞。比如負責用戶認證的過濾器,如果遇到未認證的對等體發出的I/O事件,則會直接關閉連接。這可以保證這些事件不會通過此過濾器到達I/O處理器。

表3.IoFilter中與過濾器的生命周期相關的方法

init():當過濾器第一次被添加到過 濾器鏈中的時候,此方法被調用。用來完成過濾器的初始化工作。

onPreAdd(IoFilterChainparent,Stringname,IoFilter.NextFilternextFilter): 當過濾器即將被添加到過濾 器鏈中的時候,此方法被調用。

onPostAdd(IoFilterChainparent,String name,IoFilter.NextFilternextFilter):當過濾器已經被添加到過濾器鏈中之後,此方法被調用

onPreRemove(IoFilterChainparent,Stringname,IoFilter.NextFilternextFilter):當過濾器即將被從過濾器鏈中刪除的時候,此方法被調用。
onPostRemove(IoFilterChainparent,Stringname,IoFilter.NextFilternextFilter):當過濾器已經被從過濾器鏈中刪除的時候,此方法被調用。
destroy():當過濾器不再需要的時候,它將被銷毀,此方法被調用

參數parent表示包含此過濾器的過濾器鏈,參數name表示過濾器的名稱,參數nextFilter表示過濾器鏈中的下一個過濾器。

filterClose(IoFilter.NextFilternextFilter,IoSessionsession):濾對IoSession的close方法的調用。
filterWrite(IoFilter.NextFilternextFilter,IoSessionsession,WriteRequestwriteRequest):濾對IoSession的write方法的調用。
exceptionCaught(IoFilter.NextFilternextFilter,IoSessionsession,Throwablecause):濾對IoHandler的exceptionCaught方法的調用。

messageReceived(IoFilter.NextFilternextFilter,IoSessionsession,Objectmessage):過濾對IoHandler的messageReceived方法的調用。

messageSent(IoFilter.NextFilternextFilter,IoSessionsession,WriteRequestwriteRequest):過濾對IoHandler的messageSent方法的調用。

sessionClosed(IoFilter.NextFilternextFilter,IoSessionsession):過濾對IoHandler的sessionClosed方法的調用。
sessionCreated(IoFilter.NextFilternextFilter,IoSessionsession):過濾對IoHandler的sessionCreated方法的調用。
sessionIdle(IoFilter.NextFilternextFilter,IoSessionsession,IdleStatusstatus):過濾對IoHandler的sessionIdle方法的調用。

sessionOpened(IoFilter.NextFilternextFilter,IoSessionsession):過濾對IoHandler的sessionOpened方法的調用。

code example:

public void messageReceived(NextFilternextFilter,IoSessionsession,Objectmessage){
if(!isON(session)){
    nextFilter.messageReceived(session,message);

}else{
           endSession(session);

}

}
private void endSession(IoSessionsession){
    session.close(true);

}

6.過濾器鏈(IoFilterChain)

過濾器只有在添加到過濾器鏈中的時候才起作用。過濾器鏈是過濾器的容器。過濾器鏈與I/O會話是一一對應的關係.

IoFilterChain介面的方法方法說明:
addFirst(String name,IoFilterfilter filter):將指定名稱的過濾器添加到過濾器鏈的開頭。
addLast(String name,IoFilterfilter filter):將指定名稱的過濾器添加到過濾器鏈的末尾。

contains(String name)判斷過濾器鏈中是否包含指定名稱的過濾器。

get(String name):從過濾器鏈中獲取指定名稱的過濾器。

remove(String name):從過濾器鏈中刪除指定名稱的過濾器。
replace(String name,IoFilter newFilter):用過濾器newFilter替換掉過濾器鏈中名為name的過濾器。

getSession():獲取與過濾器鏈一一對應的I/O會話

7.I/O處理器(IoHandlerAdapter)

I/O事件通過過濾器鏈之後會到達I/O處理器。I/O處理器中與I/O事件對應的方法會被調用。ApacheMINA中org.apache.mina.core.service.IoHandler是I/O處理器要實現的介面,一般情況下,只需要繼承自org.apache.mina.core.service.IoHandlerAdapter並覆寫所需方法即可。

IoHandler介面的方法:

sessionCreated(IoSessionsession)當有新的連接建立的時候,該方法被調用。

sessionOpened(IoSessionsession)當有新的連接打開的時候,該方法被調用。該方法在sessionCreated之後被調用。
sessionClosed(IoSessionsession)當連接被關閉的時候,此方法被調用。

sessionIdle(IoSessionsession,IdleStatusstatus)當連接變成閑置狀態的時候,此方法被調用。
exceptionCaught(IoSessionsession,Throwablecause)當I/O處理器的實現或是ApacheMINA中有異常拋出的時候,此方法被調用。
messageReceived(IoSessionsession,Objectmessage)當接收到新的消息的時候,此方法被調用。

messageSent(IoSessionsession,Objectmessage)當消息被成功發送出去的時候,此方法被調用。

其中

1.sessionCreated和sessionOpened的區別:

sessionCreated方法是由I/O處理線程來調用的,而sessionOpened是由其它線程來調用的。因此從性能方面考慮,不要在sessionCreated方法中執行過多的操作。

2.sessionIdle,預設情況下,閑置時間設置是禁用的,也就是說sessionIdle並不會被調用。可以通過IoSessionConfig.setIdleTime(IdleStatus,int)來進行設置

 

常用方法:

1. WriteFuture的使用
IoSessionsession=...;//獲取I/O會話對象
WriteFuturefuture=session.write("HelloWorld");//發送數據

future.awaitUninterruptibly();//等待發送數據操作完成

if(future.isWritten()){
//數據已經被成功發送}else{
//數據發送失敗}
由於這樣的需求很常見,I/O處理器中提供了messageSent方法,當數據發送成功的時候,該方法會被調用。

2. JMX集成ApacheMINA可以集成JMX來對網路應用進行管理和監測。

MBeanServermBeanServer=ManagementFactory.getPlatformMBeanServer();

IoAcceptoracceptor=newNioSocketAcceptor();
IoServiceMBeanacceptorMBean=newIoServiceMBean(acceptor);

ObjectNameacceptorName=newObjectName(acceptor.getClass().getPackage().getName()+":type=acceptor,name="+acceptor.getClass().getSimpleName));

mBeanServer.registerMBean(acceptorMBean,acceptorName);


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 解決辦法:給img定義vertical align或者定義為塊狀。 最優的解決辦法是:定義vertical align,註:定義vertical align為middle時在IE6中大概還有一像素的頂邊距,最好為top或bottom。 還有種極端解決辦法就是:將父容器的字體大小為零,font siz ...
  • 有三種方法能夠確定瀏覽器視窗的尺寸(瀏覽器的視口,不包括工具欄和滾動條)。 對於Internet Explorer、Chrome、Firefox、Opera 以及 Safari: 瀏覽器視窗的內部高度:window.innerHeight 瀏覽器視窗的內部寬度:window.innerWidth 對 ...
  • 今天,開始學習第二節!!! 工欲善其事,必先利其器 react推薦我們使用webpack來打包文件,那麼我們就用吧!(其實真心不想用啊) 至於好處網上寫的天花亂墜的,大家自行解決啊... 這節主要就學習怎麼配置webpack了,這玩意我搗鼓了整整一天才弄的一知半解,哎,腦子差就是吃虧... 1.提前 ...
  • 在寫這篇文章之前,我詢問了在唯品會和騰訊的童鞋、以及公司裡面前端大神(深哥),對於設計稿切圖的詳細方法,經過對比驗證,得出設計稿轉換頁面單位尺寸方法步驟。我分別詢問下麵四個問題: 1. 設計稿的單位是什麼,一般大小是什麼? 2. 頁面長度單位用什麼,px、em、rem,還是混合,如果用rem,htm ...
  • 查看效果:http://hovertree.com/texiao/mobile/10/或者手機掃描二維碼查看效果: 效果圖:代碼如下: 轉自:http://hovertree.com/h/bjaf/loucldil.htm 推薦:http://hovertree.com/hvtart/bjae/jf ...
  • 在我們的項目中,有大量ajax查詢表單+結果列表的頁面,由於查詢結果是ajax返回的,當用戶點擊列表的某一項進入詳情頁之後,再點擊瀏覽器回退按鈕返回ajax查詢頁面,這時大家都知道查詢頁面的表單和結果都回到了預設狀態。 如果每次返回頁面都要重新輸入查詢條件,或有甚者還得轉到列表的第幾頁,那這種體驗用 ...
  • 外部樣式為: 通過 和 是無效的 要想修改div的width,可以通過如下這種方式: 要想修改多個屬性,可以這麼做: ...
  • 當我們使用activity加fragment的時候,每個界面都要建立一個fragment,每個fragment裡面都要重寫onCreate(),onCreateView(),onActivityCreated(),方法,我們新建一個基類BaseFragment來重寫這些方法 BaseFragment ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...