Mina框架研究(1)

Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。

这个框架的优点:

– 异步
– 无阻塞
– 事件驱动
– 支持TCP, UDP, APR, 串口…
– 通过 过滤器(Filters)实现扩展性
– 同时提供协议框架

 

总体框架

之前的一个项目用到了MINA,最近想再系统的整理一下,主要参考MINA 2.0 User Guide

基于MINA框架的应用程序架构应该是这样的:

apparch_small

底层是基于JAVA的NIO 1.0实现的;

其核心部分架构是这样的:

mina_app_arch

 

内部可以分为3 个层次:

I/O Service - 执行实际的I / O,可以选择现成的Services如 (*Acceptor),也可以自己写。

I/O Filter Chain - 这是一个由多个过滤器组成的过滤器链,在这个环节将字节数据转换到特定的数据结构中(Filters/Transforms bytes into desired Data Structures and vice-versa)
I/O Handler - 实际的业务逻辑部分

 

Server端应用

对socket通信来说,使用比较广泛的是基于Server端的应用,尤其是并发规模达到一定程度后,颇具挑战性。那么我们来看一下,基于MINA框架的Server端应用:

1、IOAcceptor 监听指定的端口,处理新的网络连接;一旦一个新的连接到达后,IOAcceptor 就产生一个session,后续所有从这个IP和端口发送过来的请求就将通过这个Session被处理。

2、Session创建后,后续所有的数据包都被人到过滤器链中,通过过滤器将原始的字节码转变成高层的对象,这个环节PacketEncoder/Decoder就十分有用。

3、最后数据包或对象被传送给Handler做业务逻辑处理;

无标题

Main.java:

public class Main {
private static final int PORT = 9123;
/**
* @param args the command line arguments
*/
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));

}

}

1、创建IoAcceptor;

2、加入日志记录和解码的过滤器,其中日志过滤器用SL4J库记录信息,而编码过滤器则解码所有收到的信息。使用 new TextLineCodecFactory() 发送的信息迕行编码,返是MINA自带的,功能有限,只能处理文本戒者String类型。

3、设置ServerHandler,这里是一个自定义的Handler:TimeServerHandler;

4、设置Session的对应的I/O processor 读缓存区大小2048;通常这个参数不需要设置;

5、设置空闲时间,这里的BOTH_IDLEEADER_IDLEWRITER_IDLE. 都为10秒;

6、绑定监听端口9123;

TimeServerHandler.java:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package minatest1;

/**
*
* @author THINKPAD
*/

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 ));
}
}

这里主要有一下几个主要的方法:

messageReceived(…),对接收到的消息(已经解码)迕行下一步处理,这里对收到的字符串进行判断,如果是”quit”则断开连接;否则输出当前时间的字符串格式;

exceptionCaught(…),自定义异常处理, 要不然异常会被“吃掉”;

sessionIdle,当Session处于IDLE状态的时候,输出空闲状态次数;

 

 

测试,输入:telnet 127.0.0.1 9123,随便输入一串字符串,显示当前的时间:

image

 

IO Service

待续

posted @ 2012-09-06 21:17  红心李  阅读(16205)  评论(0编辑  收藏  举报