Mina框架学习

Apache MINA(Multipurpose Infrastructure for Network Applications)为开发高性能和高可性的网络应用程序提供了非常便利的框架。

Mina框架学习_第1张图片

基于MINA框架的应用程序架构应该是这样的,底层基于JAVA的NIO 1.0实现的。

 

Mina框架学习_第2张图片

(1)IO Service执行实际的IO。

(2)IO Filter Chain是一个由多个过滤器组成的过滤链,这个环节将字节数据转换到待定的数据结构中。

(3)IO Handler执行实现的业务逻辑部分。

基于MINA框架的Server端应用:

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

(2)后续所有数据包通过过滤器将原始的字节码转变成高层的对象。

(3)Handler做业务逻辑处理。

 

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

    }

}

 

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


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

 

 

IoService

它是一个接口,有两种实现,IoAcceptor和IoConnector。将者是针对Server端实现,后者是针对Client端的实现。

1.IoAcceptor在Mina中提供了多种实现:

(1)NioSocketAcceptor:无阻塞的Socket,TCP

(2)NioDatagramAcceptor:无阻塞的Socke,UDP

(3)AprSocketAcceptor:阻塞的Socket,基于APR

(4)VmPipeSocketAcceptor:the in-VM Acceptor

2.IoConnector的实现:

(1)NioSocketConnector:TCP

(2)NioDatagramConnector:UDP

(3)AprSocketConnector:APR

(4)ProxyConnector:一个支持代理服务的Connector,通过截取连接的请求,并将终端指向代理设置的地址。

(5)SerialConnector:针对串口传输的Connector

(6)VmPipeConnector:the in-VM Connector

任何时候只要有新的连接到来,都会生成一个Session对象,并且一致保存在内存中,只到连接断开。

 

IoBuffer

IoBuffer是MINA内部使用的一个byte buffer,MINA并没有直接使用NIO的ByteBuffer,不过IoBuffer是对ByteBuffer的一个封装。

1.capacity

最多能缓冲多少个元素,也是Buffer最大存储元素数,这个值是在创建Buffer的时候指定的,且不能修改。

2.position

Buffer实例上也就是个array,position变量用来跟踪截止目前为止已经写了多少数据,如果已经从Channel中读出了3个字节,Buffer的position会被置为3.指向array中第四个位置。

3.limit

从buffer向channel中写数据时,limit变量指示还剩多少数据可以读取,从channel中读取数据到buffer中时,limit变量指示还剩多少空间可供存放数据。

4.mark

在调用reset()方法时会将缓冲区的position重置为该索引,并非总是需要定义Mark,但是在定义mark时,不能将其定义为负数,也不能让它大于position,如果定义了mark,则在该position或者limit调整为小于该mark值时,该mark将被丢弃。

因为IoBuffer是一个抽象类,不能直接实现化,所有使用的时候需要调用allocate方法来进行内存分配。

 

 

   1: // Allocates a new buffer with a specific size, defining its type (direct or heap)
   2: public static IoBuffer allocate(int capacity, boolean direct)
   3:  
   4: // Allocates a new buffer with a specific size
   5: public static IoBuffer allocate(int capacity)


direct:如果为true,则得到direct buffer,如果为false,则得到heap buffer。

 

Direct Buffer不是分配在堆上的,它不被GC直接管理(但Direct Buffer的Java对象是归GC管理的,只要GC回收了它的Java对象,操作系统才会释放Direct Buffer所申请的空间)。当我们把一个Heap Buffer写入Channel的时候,实际上底层实现会先构建一个临时的Direct Buffer,然后把Heap Buffer的内容复制到这个临时的Direct Buffer上,再把这个Direct Buffer写出去。因此把一个Direct Buffer写入一个Channel的速度比把一个Heap Buffer写入一个Channel的速度要快。

IoBuffer允许生成一个自动扩展的buffer,通过设置AutoExpand属性即可。

 

最后欢迎大家访问我的个人网站:1024s

你可能感兴趣的:(软件架构)