<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent.Chan‘s Blog

    常用鏈接

    統(tǒng)計

    積分與排名

    網(wǎng)站

    最新評論

    MinaTutorialInChinese

    MinaTutorialInChinese

    MINA Tutorial 中文版: A Date with MINA

    作者: TrustinLee

    譯者: [WWW] Donald

    該手冊為使用中的用戶而寫,用戶可隨意改進該手冊。

    目錄

    1. MINA Tutorial 中文版: A Date with MINA
      1. 目錄
      2. 概述
        1. MINA是什么?
      3. I/O 層: 編寫一個 Echo Server
        1. IoSession
        2. IoHandler
        3. 實現(xiàn) IoHandler 以及啟動代碼
        4. 添加IoFilters
      4. 協(xié)議層: 實現(xiàn)反轉(zhuǎn)Echo協(xié)議
        1. ProtocolSession
        2. ProtocolHandler
        3. ProtocolEncoder 和 ProtocolDecoder
        4. 實現(xiàn) ProtocolHandler
        5. 實現(xiàn) ProtocolProvider 以及啟動代碼
        6. 添加 ProtocolFilters
      5. 高級主題
        1. ByteBuffers
          1. ByteBuffer 池
        2. 線程模式
        3. 更復雜的協(xié)議支持
        4. VM 內(nèi)部管道通訊
      6. How to Contribute
        1. How to Contact Us
        2. How to Report Bugs
        3. How Issues
      7. Acknowledgements

    概述

    現(xiàn)在已經(jīng)是World Wide Web的時代,無數(shù)的web應用框架被創(chuàng)造出來從而大大的提高了web開發(fā)的速度。拋開WWW的這個優(yōu)勢,我們知道還有很多協(xié)議是HTTP協(xié)議所無法替代的。有時,我們?nèi)匀恍枰獦?gòu)造c/s應用來實現(xiàn)適當?shù)膮f(xié)議。

    MINA是什么?

    你有沒有曾經(jīng)使用java或者其他語言實現(xiàn)過某個協(xié)議棧?就像你所經(jīng)歷過的那樣,編寫網(wǎng)絡(luò)應用即使對于有經(jīng)驗的開發(fā)者也不是容易的事情。這歸咎于以下幾個方面:

    • 沒有為開發(fā)者設(shè)計的合適的網(wǎng)絡(luò)應用框架.

      • 使你無法在有限的時間內(nèi)創(chuàng)建你的應用.

    • 網(wǎng)絡(luò)I/O編碼,消息的編/解碼,業(yè)務邏輯常常糾纏在一起.

      • 使程序失去可維護性和可復用性

    • 網(wǎng)絡(luò)應用難于進行單元測試

      • 你失去了敏捷性

    MINA是一個網(wǎng)絡(luò)應用框架,在不犧牲性能和可擴展性的前提下用于解決上面的所有問題。

    I/O 層: 編寫一個 Echo Server

    MINA包含兩層:IO層和協(xié)議層。我們首先僅使用IO層來實現(xiàn)一個echo服務,因為協(xié)議層通常是建立在IO層之上的。

    Arch1.gif

    上面的圖展示了MINA的IO層同客戶端的交互。IoAcceptor執(zhí)行所有底層IO,將他們翻譯成抽象的IO事件,并把翻譯過的事件和關(guān)聯(lián)的IoSession 發(fā)送給IoHandler

    IoSession

    IoSession.gif

    一個代表了IoSession程序同一個遠程實體的IO連接。通過IoSession,你可以寫出message到遠程實體,訪問session的配置,并且更改session的屬性。

    IoHandler

    IoHandler.gif

    • sessionCreated: 當一個IO連接建立時被調(diào)用,這個方法在任何IO操作之前被調(diào)用,以便socket參數(shù)或session屬性能夠最先被設(shè)置。

    • sessionOpened: 在sessionCreated調(diào)用之后被調(diào)用。

    • sessionClosed: 當IO連接被關(guān)閉時被調(diào)用。

    • sessionIdle: 當在遠程實體和用戶程序之間沒有數(shù)據(jù)傳輸?shù)臅r候被調(diào)用。

    • exceptionCaught: 當IoAcceptor 或者你的IoHandler.中出現(xiàn)異常時被調(diào)用。

    • dataRead: 當從遠程實體讀取數(shù)據(jù)時被調(diào)用。

    • dataWritten: 當你想遠程實體發(fā)出請求時被調(diào)用

    下面我們看看如何實現(xiàn)echo協(xié)議的IoHandler

    實現(xiàn) IoHandler 以及啟動代碼

    通常,應用需要繼承IoHandlerAdapter并實現(xiàn)需要的方法:

    package org.apache.mina.examples.echoserver;

    import org.apache.mina.common.*;
    import org.apache.mina.io.*;

    public class EchoProtocolHandler extends IoHandlerAdapter
    {
    public void sessionCreated( IoSession session )
    {
    SessionConfig cfg = session.getConfig();
    if( cfg instanceof SocketSessionConfig )
    {
    SocketSessionConfig scfg = ( SocketSessionConfig ) cfg ) ;
    scfg.setSessionReceiveBufferSize( 2048 );
    }
    }

    public void exceptionCaught( IoSession session, Throwable cause )
    {
    session.close();
    }

    public void dataRead( IoSession session, ByteBuffer rb )
    {
    // Write the received data back to remote peer
    ByteBuffer wb = ByteBuffer.allocate( rb.remaining() );
    wb.put( rb );
    wb.flip();
    session.write( wb, null );
    }
    }

    剛剛我們使用MINA實現(xiàn)echo協(xié)議,現(xiàn)在我們將handler綁定到一個server端口上。

    package org.apache.mina.examples.echoserver;

    import org.apache.mina.common.*;
    import org.apache.mina.io.*;
    import org.apache.mina.io.filter.*;
    import org.apache.mina.registry.*;

    public class Main
    {
    /** Choose your favorite port number. */
    private static final int PORT = 8080;


    public static void main( String[] args ) throws Exception
    {
    ServiceRegistry registry = new SimpleServiceRegistry();

    // Bind
    Service service = new Service( "echo",
    TransportType.SOCKET, PORT );
    registry.bind( service, new EchoProtocolHandler() );

    System.out.println( "Listening on port " + PORT );
    }
    }

    添加IoFilters

    IoFilter提供了更加有力的方式來擴展MINA。它攔截所有的IO事件進行事件的預處理和后處理。你可以把它想象成Servlet的filters。IoFilter能夠?qū)崿F(xiàn)以下幾種目的:

    • 事件日志

    • 性能檢測

    • 數(shù)據(jù)轉(zhuǎn)換(e.g. SSL support)

    • 防火墻…等等

    Arch2.gif

    我們的echo協(xié)議handler不對任何IO事件進行日志。我們可以通過添加一個filter來增加日志能力。MINA提供了IoLoggingFilter來進行日志。我們只要添加日志filter到ServiceRegistry即可。

    private static void addLogger( ServiceRegistry registry )
    {
    IoAcceptor acceptor =
    registry.getIoAcceptor( TransportType.SOCKET );
    acceptor.getFilterChain().addLast( "logger",
    new IoLoggingFilter() );
    System.out.println( "Logging ON" );
    }

    想使用SSL?MINA也提供了一個SSL的filter,但它需要JDK1.5。

    private static void addSSLSupport( ServiceRegistry registry )
    throws Exception
    {
    SSLFilter sslFilter =
    new SSLFilter( BogusSSLContextFactory.getInstance( true ) );
    IoAcceptor acceptor =
    registry.getIoAcceptor( TransportType.SOCKET );
    acceptor.getFilterChain().addLast( "sslFilter", sslFilter );
    System.out.println( "SSL ON" );
    }

    協(xié)議層: 實現(xiàn)反轉(zhuǎn)Echo協(xié)議

    在上面我們通過簡單的echo server的例子學習了如何使用IO層,但是如果想實現(xiàn)復雜的如LDAP這樣的協(xié)議怎么辦呢?它似乎是一個惡夢,因為IO層沒有幫助你分離 ‘message解析’和‘實際的業(yè)務邏輯(比如訪問一個目錄數(shù)據(jù)庫)’。MINA提供了一個協(xié)議層來解決這個問題。協(xié)議層將ByteBuffer事件轉(zhuǎn)換成高層的POJO事件:

    Arch3.gif

    使用協(xié)議層必須實現(xiàn)5個接口:ProtocolHandler, ProtocolProvider, ProtocolCodecFactory, ProtocolEncoder, 和 ProtocolDecoder

    ProtocolClasses.gif

    可能看上去有點麻煩,但是請注意ProtocolCodecFactory, ProtocolEncoder, 和 ProtocolDecoder是 可以完全復用的;Apache的ASN1項目為MINA提供了ASN.1解碼器,更通用的解碼器如:XML、java對象序列化和簡單的文本將在MINA 的下一個版本中提供。一旦你實現(xiàn)了一個靈活的解碼器,你可以在未來的應用中復用它,即使你不打算復用你的解碼器,MINA也提供了一個很簡單的方法來實現(xiàn) 復雜的協(xié)議。(請參考高級主題) 在這一章中,我們添加一個‘反轉(zhuǎn)’server,它用于反轉(zhuǎn)它接到的所有文本,我們通過它來示范如何編寫一個協(xié)議層。

    ProtocolSession

    ProtocolSession.gif

    ProtocolSession同IO層的IoSession同樣繼承自Session。就像前面提到的,你只需撰寫面向POJO的message而不是ByteBuffer的。ProtocolEncoder 將message對象解釋成ByteBuffers以便IO層能夠?qū)⑺麄冚敵龅絪ocket。

    ProtocolHandler

    ProtocolHandler類似于IO層的IoHandler.dataRead和dataWritten方法被替換成messageReceived和messageSent。這是因為ProtocolDecoder 已經(jīng)將IO層接收到的 ByteBuffers轉(zhuǎn)換成了message對象。

    ProtocolEncoder 和 ProtocolDecoder

    ProtocolCodec.gif

    ProtocolEncoderProtocolDecoder只有一個方法。ProtocolEncoder將message對象轉(zhuǎn)換成一個ByteBuffer,而ProtocolDecoder將一個ByteBuffer轉(zhuǎn)換成message對象。下面我們將學習如何實現(xiàn)這些接口。

    實現(xiàn) ProtocolHandler

    讓我們首先實現(xiàn)一個ProtocolHandler。如同剛才實現(xiàn)IoHandler那樣,我們繼承ProtocolHandlerAdapter

    package org.apache.mina.examples.reverser;

    import org.apache.mina.protocol.*;

    public class ReverseProtocolHandler extends ProtocolHandlerAdapter
    {
    public void exceptionCaught( ProtocolSession session,
    Throwable cause )
    {
    // Close connection when unexpected exception is caught.
    session.close();
    }

    public void messageReceived( ProtocolSession session,
    Object message )
    {
    // Reverse reveiced string
    String str = message.toString();
    StringBuffer buf = new StringBuffer( str.length() );
    for( int i = str.length() - 1; i >= 0; i-- )
    {
    buf.append( str.charAt( i ) );
    }

    // and write it back.
    session.write( buf.toString() );
    }
    }

    實現(xiàn) ProtocolProvider 以及啟動代碼

    要實現(xiàn)反轉(zhuǎn)協(xié)議要實作的唯一接口就是ProtocolProvider。它非常簡單: (注:Provider用于在一個統(tǒng)一的類中提供該協(xié)議相關(guān)的Handler、Decoder和Encoder。)

    package org.apache.mina.examples.reverser;

    import org.apache.mina.protocol.*;

    /**
    * {@link ProtocolProvider} implementation for reverser server protocol.
    */
    public class ReverseProtocolProvider implements ProtocolProvider
    {
    // Protocol handler is usually a singleton.
    private static ProtocolHandler HANDLER =
    new ReverseProtocolHandler();

    // Codec factory is also usually a singleton.
    private static ProtocolCodecFactory CODEC_FACTORY =
    new ProtocolCodecFactory()
    {
    public ProtocolEncoder newEncoder()
    {
    // Create a new encoder.
    return new TextLineEncoder();
    }

    public ProtocolDecoder newDecoder()
    {
    // Create a new decoder.
    return new TextLineDecoder();
    }
    };

    public ProtocolCodecFactory getCodecFactory()
    {
    return CODEC_FACTORY;
    }

    public ProtocolHandler getHandler()
    {
    return HANDLER;
    }
    }

    這樣,反轉(zhuǎn)協(xié)議就被完全實現(xiàn)了。啟動的部分同echo server非常相似:

    package org.apache.mina.examples.reverser;

    import org.apache.mina.common.*;
    import org.apache.mina.protocol.*;
    import org.apache.mina.registry.*;

    /**
    * (<b>Entry point</b>) Reverser server which reverses all text lines from
    * clients.
    *
    * @author Trustin Lee (trustin@apache.org)
    * @version $Rev: 165594 $, $Date: 2005-05-02 16:21:22 +0900 $,
    */
    public class Main
    {
    private static final int PORT = 8080;

    public static void main( String[] args ) throws Exception
    {
    ServiceRegistry registry = new SimpleServiceRegistry();

    // Bind
    Service service = new Service( "reverse", TransportType.SOCKET, PORT );
    registry.bind( service, new ReverseProtocolProvider() );

    System.out.println( "Listening on port " + PORT );
    }
    }

    添加 ProtocolFilters

    ProtocolFilter 同IO層的IoFilter類似:

    Arch4.gif

    添加IoLoggingFilter來記錄底層IO事件是為了debug。我們可以用ProtocolLoggingFilter代替它來記錄高層事件:

        private static void addLogger( ServiceRegistry registry )
    {
    ProtocolAcceptor acceptor = registry.getProtocolAcceptor( TransportType.SOCKET );
    acceptor.getFilterChain().addLast( "logger", new ProtocolLoggingFilter() );
    System.out.println( "Logging ON" );
    }

    高級主題

    在這里我們?yōu)镸INA的高端用戶講解一些高級話題。

    ByteBuffers

    MINA沒有直接使用使用java NIO的ByteBuffer類。它使用一個自制的ByteBuffer來擴展java NIO ByteBuffer的功能。 以下是它們的一些區(qū)別:

    • MINA ByteBuffer是一個抽象類,用戶可以自由的擴展它

    • MINA 管理 MINA ByteBuffers 并對其提供對象池. Users can control the point the buffers are released by providing acquire() and release() methods.

    • MINA ByteBuffer提供很多便利的方法,如:無符號數(shù)值的getter和基于String的getter和putter

    如果你使用MINA,你將不需要直接使用NIO buffers,因為僅使用MINA buffers就可以完成大多數(shù)buffer操作。

    ByteBuffer 池

    MINA有一個全局的ByteBuffer池,它被在同一個虛擬機下的所有MINA應用共享。任何分配的buffers將在IO操作或者事件處理方法被執(zhí)行之后被釋放。所以你可以調(diào)用ByteBuffer.allocate()來從池中得到一個ByteBuffer而不需要將它返回到池中。請查閱ByteBuffer JavaDocs獲得更多信息。

    線程模式

    MINA通過它靈活的filter機制來提供多種線程模型。沒有線程池過濾器被使用時MINA運行在一個單線程模式。如果添加了一個IoThreadPoolFilterIoAcceptor,你將得到一個leader-follower模式的線程池。如果再添加一個ProtocolThreadPoolFilter,你的server將有兩個線程池;一個(IoThreadPoolFilter)被用于對message對象進行轉(zhuǎn)換,另外一個(ProtocolThreadPoolFilter)被用于處理業(yè)務邏輯。

    SimpleServiceRegistry加上IoThreadPoolFilterProtocolThreadPoolFilter的缺省實現(xiàn)即可適用于需要高伸縮性的應用。如果你想使用自己的線程模型,請查看SimpleServiceRegistry的源代碼,并且自己初始化Acceptor。顯然,這是個繁瑣的工作。

    IoThreadPoolFilter threadPool = new IoThreadPoolFilter();
    threadPool.start();

    IoAcceptor acceptor = new SocketAcceptor();
    acceptor.getFilterChain().addLast( "threadPool", threadPool );

    ProtocolThreadPoolFilter threadPool2 = new ProtocolThreadPoolFilter();
    threadPool2.start();

    ProtocolAcceptor acceptor2 = new IoProtocolAcceptor( acceptor );
    acceptor2.getFilterChain().addLast( "threadPool", threadPool2 );

    ...

    threadPool2.stop();
    threadPool.stop();

    更復雜的協(xié)議支持

    ‘Reverser’示例相對于其他復雜的協(xié)議來說仍然過于簡單。要想讓一個server工作,仍然有許多message類型和它們的轉(zhuǎn)換的工作需要作。MINA提供了一下工具類來提供幫助:

    更多細節(jié)請參考 JavaDocs

    VM 內(nèi)部管道通訊

    你一定已經(jīng)知道協(xié)議層是建立在IO層之上的,但是有時也不一定。雖然我們通常使用協(xié)議層來包裝IO層,但仍有一種特殊的協(xié)議層實現(xiàn),稱作:’ in-VM pipe communication’ 讓我們假設(shè)你需要使用MINA實現(xiàn)一個SMTP server和一個Spam Filter server。SMTP server可能需要同Spam Filter server通訊以便發(fā)現(xiàn)spam message或者RBL中列出的客戶端。如果這兩個server是在同一個java虛擬機中,一個IO層是多余的,你可以繞過message對象的編解 碼的過程。In-VM pipe communication可以使你使用同樣的代碼而不管spam filter server是否在同一個虛擬機中。 請查看隨源碼分發(fā)的’ Tennis’示例。

    How to Contribute

    We want MINA to evolve actively, reacting to user requests, and therefore we need as much feedback from you as possible. The Apache Directory team will strive to satisfy all possible use cases of MINA. Please feel free to contact us.

    How to Contact Us

    How to Report Bugs

    You can report any bugs found from MINA to our issue tracker page. Please attach any test cases that can reproduce your issue if possible.

    How Issues

    Any patches and comments are welcome! You can browse the list of unresolved issues in JIRA:

    Or, you could do some performance benchmarks on MINA and tune it.

    Acknowledgements

    MINA couldn’t exist without strong support of many contributors:

    • The Apache Directory team for letting me join the team

    • All users of Netty2 forum and [MAILTO] dev@directory.apache.org for great feedbacks

    • Jan Andersson and his team for SSLFilter

    • Vel Pandian for enabling client mode for SSLFilter

    • Vinod Panicker for performance benchmark and active feedbacks

    last edited 2005-10-15 08:59:33 by Donald

    posted on 2006-02-27 23:52 Vincent.Chen 閱讀(737) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 日本免费一区尤物| 黄页网站免费在线观看| 亚洲成a人片在线观看国产| 亚洲中文无码卡通动漫野外| 91高清免费国产自产| 亚洲黄色在线观看视频| 伊人久久免费视频| 亚洲国产精品成人久久久| 免费在线观看视频网站| 天堂亚洲国产中文在线| 成人a免费α片在线视频网站 | 免费在线观看你懂的| 菠萝菠萝蜜在线免费视频| 免费人成在线观看视频播放| 亚洲天堂免费在线视频| 人人狠狠综合久久亚洲88| 99视频免费观看| 亚洲国产最大av| 国产精品免费综合一区视频| 一级毛片视频免费观看| 久久国产亚洲精品麻豆| 国产成人精品免费视频动漫| 亚洲午夜精品一区二区麻豆| 免费乱码中文字幕网站| a在线观看免费视频| 亚洲嫩草影院在线观看| 国产精品久久香蕉免费播放| 国产精品内射视频免费| 亚洲视频在线观看网站| 青草草在线视频永久免费| 成人a毛片免费视频观看| 亚洲AV午夜成人片| 18禁超污无遮挡无码免费网站国产| 无码天堂亚洲国产AV| 欧洲亚洲国产清在高| 久久久久久国产精品免费免费| 美女黄频免费网站| 久久久无码精品亚洲日韩按摩 | 亚洲免费视频在线观看| 免费看美女被靠到爽的视频| 久久最新免费视频|