夢幻之旅

          DEBUG - 天道酬勤

             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            671 隨筆 :: 6 文章 :: 256 評論 :: 0 Trackbacks

          簡單介紹:MINA框架是對java的NIO包的一個封裝,簡化了NIO程序開發的難度,封裝了很多底層的細節,然開發者把精力集中到業務邏輯上來,最近做了一個相關的項目,為了備忘對MINA做一個總結。

          下面這個start方法用來初始化MINA:

          Java代碼
          1. private void start(int port, WebContext ctx)    
          2.       throws IOException, InstantiationException   
          3.         , IllegalAccessException, ClassNotFoundException {   
          4.     //初始化Acceptor   
          5.     NioSocketAcceptor acceptor = new NioSocketAcceptor(5);   
          6.            
          7.        java.util.concurrent.Executor threadPool = Executors.newFixedThreadPool(1500);//建立線程池   
          8.        //加入過濾器(Filter)到Acceptor   
          9.        acceptor.getFilterChain().addLast("exector"new ExecutorFilter(threadPool));   
          10. acceptor.getFilterChain().addLast("codec",    
          11.        new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));   
          12.        LoggingFilter filter = new LoggingFilter();   
          13.     filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);   
          14.     filter.setMessageReceivedLogLevel(LogLevel.DEBUG);   
          15.     filter.setMessageSentLogLevel(LogLevel.DEBUG);   
          16.     filter.setSessionClosedLogLevel(LogLevel.DEBUG);   
          17.     filter.setSessionCreatedLogLevel(LogLevel.DEBUG);   
          18.     filter.setSessionIdleLogLevel(LogLevel.DEBUG);   
          19.     filter.setSessionOpenedLogLevel(LogLevel.DEBUG);   
          20.     acceptor.getFilterChain().addLast("logger", filter);    
          21.            
          22.        acceptor.setReuseAddress(true);//設置的是主服務監聽的端口可以重用   
          23.            
          24.        acceptor.getSessionConfig().setReuseAddress(true);//設置每一個非主監聽連接的端口可以重用   
          25.        acceptor.getSessionConfig().setReceiveBufferSize(1024);//設置輸入緩沖區的大小   
          26.        acceptor.getSessionConfig().setSendBufferSize(10240);//設置輸出緩沖區的大小   
          27. //設置為非延遲發送,為true則不組裝成大包發送,收到東西馬上發出   
          28.        acceptor.getSessionConfig().setTcpNoDelay(true);   
          29. //設置主服務監聽端口的監聽隊列的最大值為100,如果當前已經有100個連接,再新的連接來將被服務器拒絕   
          30.        acceptor.setBacklog(100);   
          31.        acceptor.setDefaultLocalAddress(new InetSocketAddress(port));   
          32.        //加入處理器(Handler)到Acceptor   
          33.        acceptor.setHandler(new WebHandler());   
          34.     acceptor.bind();   
          35. }  

           NioSocketAcceptor是MINA的適配器,一切都是從這里開始的。MINA中有個過濾器和處理器的概念,過濾器用來過濾數據,處理器用來處理數據。具體來說MINA的處理模型就是request->過濾器A->過濾器B->處理器->過濾器B->過濾器A->response,這里的request和response類似serlvet的request和response。

          Java代碼
          1. acceptor.getFilterChain().addLast("exector"new ExecutorFilter(threadPool));   
          2. //加入一個線程池到適配器,這里用的是jdk自帶的線程池  
           
          Java代碼
          1.  acceptor.getFilterChain().addLast("codec",    
          2.         new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));   
          3. //這里是處理邏輯的關鍵部位,請求的處理都是在 WebDecoder類和WebEncoder類中處理,可以明顯從命名上看出來一個是用來解碼,另一個是用來編碼,requet過來后先進入 WebDecoder類(實現了ProtocolDecoder接口)進行解碼處理,這里可以加入自己的邏輯把傳進來的流解碼成自己需要的信息。而 WebEncoder類(實現了ProtocolEncoder接口)是進行編碼,在這個類里面加入自己的邏輯把處理后的信息組裝發送給客戶端 (response)。而在解碼和編碼過程中WebHandler(擴展了IoHandlerAdapter抽象類)起到了處理器的作用。   
          4. //request->WebDecoder->WebHandler->WebEncode->response  

           

          現在詳細描述一下request->WebDecoder->WebHandler->WebEncode->response的過程:

          客戶端發送一個請求到MINA服務器,這里相當于來了一個requet。請求首先來到

          Java代碼
          1. WebDecoder類(實現了ProtocolDecoder接口)中的    
          2. boolean decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception{}方法   
          3. /*  
          4. 參數in:用戶請求信息全存在這里,讀數據就從in這里讀。  
          5. 參數out:用來輸出處理后的數據到Filter的下一個過濾器,如果沒有過濾器了就輸出到WebHandler,這里有點和  
          6. servelt的過濾器類似。利用out.write(Object object);這個函數可以把數據傳到下一個Filter。我們可以自己定義  
          7. 一個對象,我們假設為Request,用它來傳遞消息,那末這里就可以寫成out.write(new RequsetMessage());  
          8. 如果這個方法返回false,就是說當前邏輯包還沒接收完(也就是當前的IoBuffer并沒有包含足夠的數據),需要再次  
          9. 執行decode方法(再次獲取新的IoBuffer),用來獲取足夠的數據。如果返回值為true就表示可以不執行decode方  
          10. 法了,但是要激活handler方法,必須要調用out.write方法。  
          11. public class RequestMessage{}//這里什么也不做  
          12. */  

           然后到

          Java代碼
          1. WebHandler(擴展了IoHandlerAdapter抽象類)中的   
          2. void messageReceived(IoSession session, Object message) throws Exception{}方法   
          3. WriteFuture future = session.write(response);//session中必須加入這個代碼,才會激活encode方法   
          4. future.addListener(IoFutureListener.CLOSE);//這個的作用是發送完畢后關閉連接,加了就是短連接,不然是長連接   
          5. IoFutureListener里面有個operationComplete(IoFuture future)方法,當流發送完成之后才調用這個方法。   
          6. /*  
          7. 參數message:用來獲取Filter傳遞過來的對象.對應代碼RequestMessage request = (RequestMessage) message;  
          8. 參數session:用來發送數據到Filter.對應代碼session.write(new ResponseMessage());  
          9. public class ResponseMessage{}//這里什么也不做,假設存放處理后的數據  
          10. 注意:對于一個MINA程序而言,對于WebHandler類只生成一個對象,所以要考慮線程安全問題  
          11.  */  
           

          然后到

          Java代碼
          1. WebEncoder類(實現了ProtocolEncoder接口)中的   
          2. boolean encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception{}    
          3. 方法   
          4. /*  
          5. 參數message:用來獲取上一個Filter節點的數據或者處理器的數據(如果這個過濾器為最靠近處理器的那個)  
          6. ResponseMessage response = (ResponseMessage)message;  
          7. 參數out:用來輸出數據到下一個Filter節點過或者到客戶端,用out.write(Object encodedMessage)把數據發送  
          8. 出去,但是要注意的是,如果這個Filter下一個節點如果是客戶端的話,那個這個encodedMessage數據必須為  
          9. IoBuffer類型的,可以利用IoBuffer.wrap(byte[] byteArray)這個方法來格式化輸出數據  
          10. */  
          posted on 2011-09-04 02:28 HUIKK 閱讀(500) 評論(0)  編輯  收藏 所屬分類: java Net
          主站蜘蛛池模板: 高邮市| 永和县| 辉县市| 北辰区| 新晃| 贵港市| 仙居县| 西安市| 苏尼特右旗| 滕州市| 杭锦旗| 洛隆县| 西城区| 巍山| 浮山县| 北辰区| 吉木乃县| 延庆县| 牟定县| 邵阳县| 遂昌县| 达日县| 苗栗市| 凤台县| 金溪县| 安远县| 萝北县| 纳雍县| 古丈县| 清原| 浙江省| 大兴区| 武陟县| 峨边| 芜湖市| 阜阳市| 聊城市| 黄梅县| 大关县| 绥江县| 温宿县|