Apache MINA 快速入門
http://hi.baidu.com/ofbase/blog/item/9acf45d05989f88ea1ec9c11.html
Added by Mark Webb, last edited by Trustin Lee on Apr 16, 2007 (view change)
1 簡(jiǎn)介
建立一個(gè)基于MINA的時(shí)間服務(wù)器,下面的內(nèi)容需要先準(zhǔn)備好。
MINA 1.1 Core
JDK 1.5 or greater
SLF4J 1.3.0 or greater
>>Log4J 1.2 users: slf4j-api.jar, slf4j-log4j12.jar, and Log4J 1.2.x
>>Log4J 1.3 users: slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.x
>>java.util.logging users: slf4j-api.jar and slf4j-jdk14.jar
這個(gè)程序只測(cè)試了Windows2000pro和Linux系統(tǒng),并且在做的時(shí)候沒(méi)有依賴于一些開發(fā)平臺(tái)的環(huán)境。
2 編寫MINA時(shí)間服務(wù)
下面先建立一個(gè)文件MinaTimeServer.java,代碼如下:
public class MinaTimeServer {
public static void main(String[] args) {
// code will go here next
}
}
下面會(huì)慢慢將這個(gè)類寫完,這里先定義一個(gè)main用于啟動(dòng)程序。這一步結(jié)束后,還需要一個(gè)監(jiān)聽連接的對(duì)象,因?yàn)檫@個(gè)程序是基于TCP/IP的,這里將增加一個(gè)SocketAcceptor。
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
public class MinaTimeServer {
public static void main(String[] args) {
// The following two lines change the default buffer type to 'heap',
// which yields better performance.
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
}
}
通過(guò)這里的SocketAcceptor類,下面將把它綁定到一個(gè)端口上,如果你想增加一個(gè)線程模型到該類的話,參考"配置線程模型"部分。
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
public class MinaTimeServer {
private static final int PORT = 9123;
public static void main(String[] args) throws IOException {
ByteBuffer.setUseDirectBuffers(false);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.getSessionConfig().setReuseAddress( true );
cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter(
new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
acceptor.bind( new InetSocketAddress(PORT), new TimeServerHandler(), cfg);
System.out.println("MINA Time server started.");
}
}
這里定義了一個(gè)整型的端口變量,呼叫SocketAcceptor.bind(SocketAddress,IoHandler,cfg),第一個(gè)參數(shù)是要監(jiān)聽的網(wǎng)址,是本地的9123端口。
第二個(gè)參數(shù)傳的是實(shí)現(xiàn)IoHandler接口的類,是服務(wù)于所有的客戶端請(qǐng)求的。在這里,將會(huì)擴(kuò)展IoHandlerAdapter類,這類遵循"適配器設(shè)計(jì)模式"的。
第三個(gè)參數(shù)是配置對(duì)象,用于配置日志和編碼過(guò)濾器。每一個(gè)信息都會(huì)通過(guò)在IoAcceptor中定義的過(guò)濾器鏈的所有過(guò)濾器。在這風(fēng)景點(diǎn),將會(huì)將信息通過(guò)日志和編碼過(guò)濾器。日志過(guò)濾器用SL4J庫(kù)記錄信息,而編碼過(guò)濾器則反編碼所有收到的信息,并且將所有TextLineCodecFactory發(fā)送的信息進(jìn)行編碼。
下面就是TimeServerHandler類的代碼:
import java.util.Date;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
public class TimeServerHandler extends IoHandlerAdapter {
public void exceptionCaught(IoSession session, Throwable t) throws Exception {
t.printStackTrace();
session.close();
}
public void messageReceived(IoSession session, Object msg) throws Exception {
String str = msg.toString();
if( str.trim().equalsIgnoreCase("quit") ) {
session.close();
return;
}
Date date = new Date();
session.write( date.toString() );
System.out.println("Message written...");
}
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
if( session.getTransportType() == TransportType.SOCKET )
((SocketSessionConfig) session.getConfig() ).setReceiveBufferSize( 2048 );
session.setIdleTime( IdleStatus.BOTH_IDLE, 10 );
}
}
這里用于管理信息,覆蓋了exceptionCaught,messageReceived和sessionCreated方法,如前所示,該類擴(kuò)展了IoHandlerAdapter。
exceptionCaught方法將會(huì)打印錯(cuò)誤并且關(guān)閉對(duì)話,對(duì)于大多數(shù)的情況來(lái)講,這是標(biāo)準(zhǔn)的處理方法,除非能從異常中恢復(fù)過(guò)來(lái)。
messageReceived方法將收到從客戶端發(fā)來(lái)的數(shù)據(jù),并且寫回當(dāng)前時(shí)間。如果收到了"quit",對(duì)話將被關(guān)閉。該方法將當(dāng)前時(shí)間發(fā)往客戶端,依賴于你使用的協(xié)議編碼,發(fā)送至方法的對(duì)象(第二個(gè)參數(shù))會(huì)有不同,發(fā)送到session.write(Object)方法的對(duì)象類同。如果你沒(méi)有指定協(xié)議編碼,則一般會(huì)收到ByteBuffer對(duì)象,而發(fā)送的也要是ByteBuffer對(duì)象。
sessionCreated方法用于對(duì)話初始化,在這里,先打印一條信息,然后判斷對(duì)話的類型,再設(shè)置緩沖大小,這里設(shè)置的是2048個(gè)字節(jié)。空閑時(shí)間設(shè)置為10秒,如果覆蓋了sessionIdle方法,則該方法每10秒被呼叫一次。
3 測(cè)試
到這里,編譯程序。如果成功,那么運(yùn)行,然后telnet這個(gè)程序,如下所示:
客戶端內(nèi)容:
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:~>
服務(wù)端內(nèi)容:
MINA Time server started.
Session created...
Message written...
4 參考文檔
Apache MINA Quick Start Guide http://mina.apache.org/documentation.html
Added by Mark Webb, last edited by Trustin Lee on Apr 16, 2007 (view change)