MINA2 之快速上手指南

参考网站:http://riddickbryant.iteye.com/blog/564318


一、介绍

 

该教程通过构建一个time server,带你走进给予MINA的应用程序开发的大门,但在开始之前我们需要具备下面的必要条件:

  • MINA 2.x的核心包
  • JDK 1.5 或更高版本
  • SLF4J 1.3.0 或更高版本
  1. Log4J 1.2的用户:slf4j-api.jar, slf4j-log4j12.jar, and Log4J 1.2.x
  2. Log4J 1.3的用户:slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.x
  3. java.util.logging的用户:slf4j-api.jar and slf4j-jdk14.jar

注意:请务必确认你所使用的slf4j-*.jar要与你的日志框架相匹配。例如,slf4j-log4j12.jar 和 log4j-1.3.x.jar不能在一起使用,否则会引起混乱。
我已经在Windows 2000 professional 和 linux平台上测试了这个程序,如果你在运行这个程序的过程中遇到了问题,请立即联系我们的开发人员。

当然,这个程序是与开发环境(IDE, editors等等)无关的,它可以在任何你熟悉的平台中运行。另外,为了简化,编译命令与运行脚本都没有体现,如果你需要学习如何编译并运行java程序,请参考Java tutorial。


二、编写基于MINA框架的time server

 

我们从创建一个名为MinaTimeServer.java的文件开始,最初的代码如下:

Java代码   收藏代码
  1. public class MinaTimeServer {   
  2.     
  3.     public static void main(String[] args) {   
  4.         // code will go here next   
  5.     }   
  6. }   

 

对所有人来说,这段代码应该是简单易懂的,我们只是简单的定义了一个main方法是这个程序能够正常运行起来。从现在开始,我们将逐步加入代码是其最终成为一个可用的server。首先,我们需要一个可以监听连接到来的对象,既然我们的程序是基于TCP/IP的,所以我们在程序中加入一个SocketAcceptor。

Java代码   收藏代码
  1. import org.apache.mina.core.service.IoAcceptor;   
  2. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;   
  3.     
  4. public class MinaTimeServer   
  5. {   
  6.     
  7.     public static void main( String[] args )   
  8.     {   
  9.         IoAcceptor acceptor = new NioSocketAcceptor();   
  10.     }   
  11.     
  12. }   

 

加入NioSocketAcceptor之后,我们可以继续定义一个handler类,并将其与NioSocketAcceptor绑定到一个端口上。

下面,我们在配置中增加一个filter,这个filter将把二进制数据或是协议相关的数据转换成为一个消息对象,反之亦然。我们使用现有的TextLine工厂类,以为它可以处理基于文本的信息(你不需要自己来实现编解码部分)。

Java代码   收藏代码
  1. import java.nio.charset.Charset;   
  2.     
  3. import org.apache.mina.core.service.IoAcceptor;   
  4. import org.apache.mina.filter.codec.ProtocolCodecFilter;   
  5. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;   
  6. import org.apache.mina.filter.logging.LoggingFilter;   
  7. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;   
  8.     
  9. public class MinaTimeServer   
  10. {   
  11.     public static void main( String[] args )   
  12.     {   
  13.         IoAcceptor acceptor = new NioSocketAcceptor();   
  14.     
  15.         acceptor.getFilterChain().addLast( "logger"new LoggingFilter() );   
  16.         acceptor.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));   
  17.     }   
  18. }   

 

然后,我们定义一个handler,这个handler将对客户端的连接以及过去当前时间的请求做出服务。handler类必须实现IoHandler接口。对于大多数基于MINA的应用程序,这个操作无疑是一个很大的负担,因为它将处理客户端说有的请求。在这个教程中,我们的handler将继承自IoHandlerAdapter,这个类依照适配器模式来简化实现IoHandler接口所带来的代码量。

Java代码   收藏代码
  1. import java.io.IOException;   
  2. import java.nio.charset.Charset;   
  3.     
  4. import org.apache.mina.core.service.IoAcceptor;   
  5. import org.apache.mina.filter.codec.ProtocolCodecFilter;   
  6. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;   
  7. import org.apache.mina.filter.logging.LoggingFilter;   
  8. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;   
  9.     
  10. public class MinaTimeServer   
  11. {   
  12.     public static void main( String[] args ) throws IOException   
  13.     {   
  14.         IoAcceptor acceptor = new NioSocketAcceptor();   
  15.     
  16.         acceptor.getFilterChain().addLast( "logger"new LoggingFilter() );   
  17.         acceptor.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));   
  18.     
  19.         acceptor.setHandler(  new TimeServerHandler() );   
  20.     }   
  21. }   

 

现在,我们在NioSocketAcceptor增加一些Socket相关的配置:

Java代码   收藏代码
  1. import java.io.IOException;   
  2. import java.nio.charset.Charset;   
  3.     
  4. import org.apache.mina.core.session.IdleStatus;   
  5. import org.apache.mina.core.service.IoAcceptor;   
  6. import org.apache.mina.filter.codec.ProtocolCodecFilter;   
  7. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;   
  8. import org.apache.mina.filter.logging.LoggingFilter;   
  9. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;   
  10.     
  11. public class MinaTimeServer   
  12. {   
  13.     public static void main( String[] args ) throws IOException   
  14.     {   
  15.         IoAcceptor acceptor = new NioSocketAcceptor();   
  16.     
  17.         acceptor.getFilterChain().addLast( "logger"new LoggingFilter() );   
  18.         acceptor.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));   
  19.     
  20.         acceptor.setHandler(  new TimeServerHandler() );   
  21. idle sessions   
  22.         acceptor.getSessionConfig().setReadBufferSize( 2048 );   
  23.         acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );   
  24.     }   
  25. }   

 

在MinaTimeServer增加了两行新的内容,这些set方法分别设置了IoHandler、input buffer size和session对象上的idle属性。buffer size指明了底层操作系统应该给与新到来的数据分配多少空间;第二行指明了什么时候应该检测idle sessions。在setIdleTime这个方法中,第一参数指明了在检测session是否idle时,应该关心那一种活动,第二个参数指明了session变为idle状态时需要经过多长的时间。

handler的代码如下:

Java代码   收藏代码
  1. import java.util.Date;  
  2.      
  3. import org.apache.mina.core.session.IdleStatus;   
  4. import org.apache.mina.core.service.IoHandlerAdapter;   
  5. import org.apache.mina.core.session.IoSession;   
  6.     
  7. public class TimeServerHandler extends IoHandlerAdapter   
  8. {   
  9.     @Override   
  10.     public void exceptionCaught( IoSession session, Throwable cause ) throws Exception   
  11.     {   
  12.         cause.printStackTrace();   
  13.     }   
  14.     
  15.     @Override   
  16.     public void messageReceived( IoSession session, Object message ) throws Exception   
  17.     {   
  18.         String str = message.toString();   
  19.         if( str.trim().equalsIgnoreCase("quit") ) {   
  20.             session.close();   
  21.             return;   
  22.         }   
  23.     
  24.         Date date = new Date();   
  25.         session.write( date.toString() );   
  26.         System.out.println("Message written...");   
  27.     }   
  28.     
  29.     @Override   
  30.     public void sessionIdle( IoSession session, IdleStatus status ) throws Exception   
  31.     {   
  32.         System.out.println( "IDLE " + session.getIdleCount( status ));   
  33.     }   
  34. }   

 

该类用到的方法有exceptionCaught、messageReceived和sessionIdle。在handler中,一定要定义exceptionCaught方法,该方法用来处理在远程连接中处理过程中发生的各种异常,如果这个方法没有被定义,我们可能不能发现这些异常。

在这个handler中,exceptionCaught方法只是简单地打印出异常堆栈信息并关闭连接,对于大多数程序来说,这是一种比较标准的操作,除非连接可以在异常条件下恢复。

messageReceived方法会接收客户端的数据并返回当前的的系统时间,如果从客户端接收到了消息‘quit’,则session会被关闭。与调用session.write(Object)的情况相同,不同的协议编解码器决定了传入该方法的对象(第二个参数)也是不同的。如果你没有指定协议编解码器,你最有可能接收到一个IoBuffer对象,当然,调用session.write(Object)也是一个IoBuffer对象。

当session持续idle的时间与acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 )设置的时间一致时,sessionIdle方法将被调用。

现在剩下的工作只是定义一个server监听的地址和端口了,当然还需要启动服务。代码如下:

 

Java代码   收藏代码
  1. import java.io.IOException;   
  2. import java.nio.charset.Charset;   
  3.     
  4. import org.apache.mina.core.session.IdleStatus;   
  5. import org.apache.mina.core.service.IoAcceptor;   
  6. import org.apache.mina.filter.codec.ProtocolCodecFilter;   
  7. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;   
  8. import org.apache.mina.filter.logging.LoggingFilter;   
  9. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;   
  10.     
  11. public class MinaTimeServer   
  12. {   
  13.     public static void main( String[] args ) throws IOException   
  14.     {   
  15.         IoAcceptor acceptor = new NioSocketAcceptor();   
  16.     
  17.         acceptor.getFilterChain().addLast( "logger"new LoggingFilter() );   
  18.         acceptor.getFilterChain().addLast( "codec"new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));   
  19.     
  20.         acceptor.setHandler(  new TimeServerHandler() );   
  21. idle sessions   
  22.         acceptor.getSessionConfig().setReadBufferSize( 2048 );   
  23.         acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );   
  24.         acceptor.setLocalAddress(new InetSocketAddress(PORT));   
  25.         acceptor.bind();   
  26.     }   
  27. }   

 

正如你所见,这里调用了acceptor.setLocalAddress( new InetSocketAddress(PORT) );方法,该方法指明了server将在哪个IP和端口上监听。最后一步调用了IoAcceptor.bind()方法,该方法将端口与具体的客户端进程绑定在一起。

三、验证Time server

 

现在,我们编译上面的程序,编译完成后就可以运行并查看运行结果了。最简单的测试途径就是启动程序,并使用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
Wed Oct 17 23:23:36 EDT 2007
quit
Connection closed by foreign host.
user@myhost:~>

MINA Time server started.
Message written...

 

四、接下来

 

获取更多资源,请浏览MINA的Documentation。你也可以阅读其他教程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值