夢幻之旅

          DEBUG - 天道酬勤

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

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

          下面這個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);//設置的是主服務監(jiān)聽的端口可以重用   
          23.            
          24.        acceptor.getSessionConfig().setReuseAddress(true);//設置每一個非主監(jiān)聽連接的端口可以重用   
          25.        acceptor.getSessionConfig().setReceiveBufferSize(1024);//設置輸入緩沖區(qū)的大小   
          26.        acceptor.getSessionConfig().setSendBufferSize(10240);//設置輸出緩沖區(qū)的大小   
          27. //設置為非延遲發(fā)送,為true則不組裝成大包發(fā)送,收到東西馬上發(fā)出   
          28.        acceptor.getSessionConfig().setTcpNoDelay(true);   
          29. //設置主服務監(jiān)聽端口的監(jiān)聽隊列的最大值為100,如果當前已經(jīng)有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中有個過濾器和處理器的概念,過濾器用來過濾數(shù)據(jù),處理器用來處理數(shù)據(jù)。具體來說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. //這里是處理邏輯的關(guān)鍵部位,請求的處理都是在 WebDecoder類和WebEncoder類中處理,可以明顯從命名上看出來一個是用來解碼,另一個是用來編碼,requet過來后先進入 WebDecoder類(實現(xiàn)了ProtocolDecoder接口)進行解碼處理,這里可以加入自己的邏輯把傳進來的流解碼成自己需要的信息。而 WebEncoder類(實現(xiàn)了ProtocolEncoder接口)是進行編碼,在這個類里面加入自己的邏輯把處理后的信息組裝發(fā)送給客戶端 (response)。而在解碼和編碼過程中WebHandler(擴展了IoHandlerAdapter抽象類)起到了處理器的作用。   
          4. //request->WebDecoder->WebHandler->WebEncode->response  

           

          現(xiàn)在詳細描述一下request->WebDecoder->WebHandler->WebEncode->response的過程:

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

          Java代碼
          1. WebDecoder類(實現(xiàn)了ProtocolDecoder接口)中的    
          2. boolean decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception{}方法   
          3. /*  
          4. 參數(shù)in:用戶請求信息全存在這里,讀數(shù)據(jù)就從in這里讀。  
          5. 參數(shù)out:用來輸出處理后的數(shù)據(jù)到Filter的下一個過濾器,如果沒有過濾器了就輸出到WebHandler,這里有點和  
          6. servelt的過濾器類似。利用out.write(Object object);這個函數(shù)可以把數(shù)據(jù)傳到下一個Filter。我們可以自己定義  
          7. 一個對象,我們假設為Request,用它來傳遞消息,那末這里就可以寫成out.write(new RequsetMessage());  
          8. 如果這個方法返回false,就是說當前邏輯包還沒接收完(也就是當前的IoBuffer并沒有包含足夠的數(shù)據(jù)),需要再次  
          9. 執(zhí)行decode方法(再次獲取新的IoBuffer),用來獲取足夠的數(shù)據(jù)。如果返回值為true就表示可以不執(zhí)行decode方  
          10. 法了,但是要激活handler方法,必須要調(diào)用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);//這個的作用是發(fā)送完畢后關(guān)閉連接,加了就是短連接,不然是長連接   
          5. IoFutureListener里面有個operationComplete(IoFuture future)方法,當流發(fā)送完成之后才調(diào)用這個方法。   
          6. /*  
          7. 參數(shù)message:用來獲取Filter傳遞過來的對象.對應代碼RequestMessage request = (RequestMessage) message;  
          8. 參數(shù)session:用來發(fā)送數(shù)據(jù)到Filter.對應代碼session.write(new ResponseMessage());  
          9. public class ResponseMessage{}//這里什么也不做,假設存放處理后的數(shù)據(jù)  
          10. 注意:對于一個MINA程序而言,對于WebHandler類只生成一個對象,所以要考慮線程安全問題  
          11.  */  
           

          然后到

          Java代碼
          1. WebEncoder類(實現(xiàn)了ProtocolEncoder接口)中的   
          2. boolean encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception{}    
          3. 方法   
          4. /*  
          5. 參數(shù)message:用來獲取上一個Filter節(jié)點的數(shù)據(jù)或者處理器的數(shù)據(jù)(如果這個過濾器為最靠近處理器的那個)  
          6. ResponseMessage response = (ResponseMessage)message;  
          7. 參數(shù)out:用來輸出數(shù)據(jù)到下一個Filter節(jié)點過或者到客戶端,用out.write(Object encodedMessage)把數(shù)據(jù)發(fā)送  
          8. 出去,但是要注意的是,如果這個Filter下一個節(jié)點如果是客戶端的話,那個這個encodedMessage數(shù)據(jù)必須為  
          9. IoBuffer類型的,可以利用IoBuffer.wrap(byte[] byteArray)這個方法來格式化輸出數(shù)據(jù)  
          10. */  
          posted on 2011-09-04 02:28 HUIKK 閱讀(500) 評論(0)  編輯  收藏 所屬分類: java Net
          主站蜘蛛池模板: 增城市| 唐海县| 新闻| 全南县| 英超| 六安市| 台安县| 柘城县| 子洲县| 迁安市| 闽清县| 通州市| 剑河县| 乐昌市| 枣阳市| 荥经县| 平顶山市| 沾益县| 冕宁县| 揭西县| 上杭县| 阳城县| 都江堰市| 海阳市| 靖江市| 理塘县| 安徽省| 南投县| 红原县| 鹿泉市| 蓬莱市| 铜川市| 巢湖市| 溆浦县| 伊吾县| 将乐县| 缙云县| 鸡西市| 黎城县| 沁源县| 南投县|