天天看点

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,会发现更多的资源。

继续阅读