天天看點

Mina架構快速入門

翻譯網址:​​http://mina.apache.org/mina-project/quick-start-guide.html​​

第一次寫了一個比較正式的譯文,如不好請指正~!

Mina架構快速入門

此教程将帶你建構一個基于Mina的程式.它将帶你建構一個時間伺服器.

此教程需要以下先決條件:

  • MINA 2.0.7 Core
  • JDK 1.5 or greater
  • [SLF4J|http://www.slf4j.org/] 1.3.0 or greater
  • Log4J 1.2users:slf4j-api.jar,slf4j-log4j12.jar, and​​Log4J​​ 1.2.x
  • Log4J 1.3users:slf4j-api.jar,slf4j-log4j13.jar, and​​Log4J​​ 1.3.x
  • java.util.loggingusers:slf4j-api.jarandslf4j-jdk14.jar
  • 重要: 請確定你使用正确的slf4j-*.jar以比對你的logging架構. 例如,slf4j-log4j12.jarandlog4j-1.3.x.jar不能一起使用, 會出故障.

我已經在Windows2000專業版和Linux上測試過程式.如果你運作該程式有任何問題請不要猶豫,聯系我們,與Mina開發者對話.同時,這個教程一直嘗試保持獨立的開發環境(IDE,編輯器...等等).此教程可運作在任何你熟知的環境下。編輯指令和步進執行此程式已經因為簡潔被移除。如果你需要學習如何編輯執行Java程式的幫助,請查閱此Java教程:

​​http://docs.oracle.com/javase/tutorial/​​

編寫MINA時間伺服器

我們将以通過建立一個名叫MinaTimeServer.java的檔案開始。初始代碼如下:

​public class MinaTimeServer {​

​​

​​

​​

​ public static void main(String[] args) {​

​​

​ // code will go here next​

​​

​ }​

​​

​}​

這段代碼對所有人來說應該是簡單的。我們簡單定義一個mian方法用來啟動程式。在這點上,我們将開始添加代碼以補足我們的伺服器。首先,我們需要一個對象用來監聽進來的連接配接。因為這個程式是基于TCP/IP的,是以我們将給我們的程式添加一個SocketAcceptor。

​import org.apache.mina.core.service.IoAcceptor;​

​​

​import org.apache.mina.transport.socket.nio.NioSocketAcceptor;​

​​

​​

​​

​public class MinaTimeServer​

​​

​{​

​​

​ public static void main( String[] args )​

​​

​ {​

​​

​ IoAcceptor acceptor = new NioSocketAcceptor();​

​​

​ }​

​​

​}​

在NioSocketAcceptor的地方,我們就可以開始定義 處理類,并将NioSocketAcceptor綁定到一個端口。

協定的

特定資料到消息對象,反之亦然。我們使用一個存在的TextLine factory(文本行工廠),因為它将為你處理文本消息(你不必再編寫編碼解碼部分了)

​import java.nio.charset.Charset;​

​​

​​

​​

​import org.apache.mina.core.service.IoAcceptor;​

​​

​import org.apache.mina.filter.codec.ProtocolCodecFilter;​

​​

​import org.apache.mina.filter.codec.textline.TextLineCodecFactory;​

​​

​import org.apache.mina.filter.logging.LoggingFilter;​

​​

​import org.apache.mina.transport.socket.nio.NioSocketAcceptor;​

​​

​​

​​

​public class MinaTimeServer​

​​

​{​

​​

​ public static void main( String[] args )​

​​

​ {​

​​

​ IoAcceptor acceptor = new NioSocketAcceptor();​

​​

​​

​​

​ acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );​

​​

​ acceptor.getFilterChain().addLast( "codec",​

  1. new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));

​ }​

​​

​}​

所有

來自用戶端進來的請求。在這個教程,我們将擴充類 IoHandlerAdapter。這個是一個擴充卡模式類,用以簡化需要編寫的代碼數量,為了滿足傳遞實作IoHandler接口的類的要求。

​import java.io.IOException;​

​​

​import java.nio.charset.Charset;​

​​

​​

​​

​import org.apache.mina.core.service.IoAcceptor;​

​​

​import org.apache.mina.filter.codec.ProtocolCodecFilter;​

​​

​import org.apache.mina.filter.codec.textline.TextLineCodecFactory;​

​​

​import org.apache.mina.filter.logging.LoggingFilter;​

​​

​import org.apache.mina.transport.socket.nio.NioSocketAcceptor;​

​​

​​

​​

​public class MinaTimeServer​

​​

​{​

​​

​ public static void main( String[] args ) throws IOException​

​​

​ {​

​​

​ IoAcceptor acceptor = new NioSocketAcceptor();​

​​

​​

​​

​ acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );​

​​

​ acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));​

​​

​​

​​

​ acceptor.setHandler( new TimeServerHandler() );​

​​

​ }​

​​

​}​

我們現在将添加NioSocketAcceptor配置。這允許我們給socket做特定的套接字設定,用來接收來自用戶端的連接配接。

​import java.io.IOException;​

​​

​import java.nio.charset.Charset;​

​​

​​

​​

​import org.apache.mina.core.session.IdleStatus;​

​​

​import org.apache.mina.core.service.IoAcceptor;​

​​

​import org.apache.mina.filter.codec.ProtocolCodecFilter;​

​​

​import org.apache.mina.filter.codec.textline.TextLineCodecFactory;​

​​

​import org.apache.mina.filter.logging.LoggingFilter;​

​​

​import org.apache.mina.transport.socket.nio.NioSocketAcceptor;​

​​

​​

​​

​public class MinaTimeServer​

​​

​{​

​​

​ public static void main( String[] args ) throws IOException​

​​

​ {​

​​

​ IoAcceptor acceptor = new NioSocketAcceptor();​

​​

​​

​​

​ acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );​

​​

​ acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));​

​​

​​

​​

​ acceptor.setHandler( new TimeServerHandler() );​

​​

​​

​​

​ acceptor.getSessionConfig().setReadBufferSize( 2048 );​

​​

​ acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );​

​​

​ }​

​​

​}​

在MinaTimeServer類裡有2行新的代碼。這些方法設定IoHandler,輸入緩沖區的大小和會話的空閑屬性。

被指定是為了告訴底層作業系統

給進來的資料

配置設定多少空間。

會話會被認為是空閑之前的

以秒為機關的時間的長度。

處理類的代碼顯示如下:

​​import java.util.Date;​​​​​​​​import org.apache.mina.core.session.IdleStatus;​​​​import org.apache.mina.core.service.IoHandlerAdapter;​​​​import org.apache.mina.core.session.IoSession;​​​​​​​​public class TimeServerHandler extends IoHandlerAdapter​​​​{​​​​    @Override​​​​    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception​​​​    {​​​​        cause.printStackTrace();​​​​    }​​​​​​​​    @Override​​​​    public void messageReceived( IoSession session, Object message ) throws Exception​​​​    {​​​​        String str = message.toString();​​​​        if( str.trim().equalsIgnoreCase("quit") ) {​​​​            session.close();​​​​            return;​​​​        }​​​​​​​​        Date date = new Date();​​​​        session.write( date.toString() );​​​​        System.out.println("Message written...");​​​​    }​​​​​​​​    @Override​​​​    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception​​​​    {​​​​        System.out.println( "IDLE " + session.getIdleCount( status ));​​​​    }​​​​}​​      

在這個類中使用的方法為

exceptionCaught, messageReceived and sessionIdle;

exceptionCaught

為了處理程序 和 處理遠端連接配接的正常過程中出現的異常,

exceptionCaught

應該總是被定義。如果這個方法沒有被定義,異常可能不被及時報告。

messageReceived

messageReceived方法 将從用戶端接收資料并寫回給用戶端以目前時間。如果從用戶端接收的消息是單詞"quit",這時 會話 将被關閉。這個方法也對用戶端列印出目前時間。依靠你使用的編碼解碼協定,進到這個方法來的對象(第二個參數)是不同的,以及你用session.write(對象)方法傳遞給這個會話的對象。如果你沒有做特定的編碼解碼協定,你将最可能接收到一個IoBuffer對象,并要求寫回一個IoBuffer對象。

sessionIdle

acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ) 

指定的

總時間,

sessionIdle方法  将被調用。

伺服器要監聽的

socket的位址,并實際調用以開啟伺服器。

代碼顯示如下:

​​import java.io.IOException;​​​​import java.net.InetSocketAddress;​​​​import java.nio.charset.Charset;​​​​​​​​import org.apache.mina.core.service.IoAcceptor;​​​​import org.apache.mina.core.session.IdleStatus;​​​​import org.apache.mina.filter.codec.ProtocolCodecFilter;​​​​import org.apache.mina.filter.codec.textline.TextLineCodecFactory;​​​​import org.apache.mina.filter.logging.LoggingFilter;​​​​import org.apache.mina.transport.socket.nio.NioSocketAcceptor;​​​​​​​​public class MinaTimeServer​​​​{​​​​    private static final int PORT = 9123;​​​​​​​​    public static void main( String[] args ) throws IOException​​​​    {​​​​        IoAcceptor acceptor = new NioSocketAcceptor();​​​​​​​​        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );​​​​        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));​​​​​​​​        acceptor.setHandler( new TimeServerHandler() );​​​​        acceptor.getSessionConfig().setReadBufferSize( 2048 );​​​​        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );​​​​        acceptor.bind( new InetSocketAddress(PORT) );​​​​    }​​​​}​​      

試驗時間伺服器

這時我們可以繼續并編譯程式。一旦你編譯成功,你就可以運作這個程式,檢測其會發生什麼。測試這個程式最便捷的方式是啟動這個程式,然後 telnet 這個程式。

Client Output Server Output

user@myhost:~> telnet 127.0.0.1 9123

Trying 127.0.0.1...

Connected to 127.0.0.1.

Escape character is '^]'.

hello

Mon Apr 09 23:42:55 EDT 2007

quit

Connection closed by foreign host.

user@myhost:~>

MINA Time server started.

Session created...

Message written...

下一步?

請通路我們使用者指導頁http://mina.apache.org/mina-project/userguide/user-guide-toc.html,會發現更多的資源。

繼續閱讀