zoukankan      html  css  js  c++  java
  • MINA学习之体系介绍

    基于MINA应用程序结构图:


    我们可以看出,MINA是应用程序(客户端或服务端)和底层基于TCP,UDP等通讯协议的网络层之间的粘合剂。而且各个模块之间是相互独立的,你只需要在MINA体

    系基础上设计你的应用程序,而不用去处理复杂的网络层。

    下图展示了MINA的内部组件以及MINA各个组件的功能。



    很显然,基于MINA的应用程序被划分为3层:

    1. I/O Service  -- 执行真正的I/O操作

    2. I/O Filter Chain -- 过滤,转换字节流为想要的数据结构

    3. I/O Handler -- 实现顶层业务逻辑 

    因此,想要创建基于MINA的应用程序,须完成以下操作:

          1. 创建 I/O Service  --从已有可用的Service(*Acceptor) 或创建你定义的

          2. 创建Filter Chain  --  从已有可有的Filter中选择或者创建自定义的Filter

          3. 创建I/O Handler  -- 写业务逻辑来处理不同的消息


    MINA服务端体系

    上文已经介绍了基于MINA应用程序的一个整体的结构,现在我们来看看服务端的结构。主要来说,服务端侦听一个端口来接受请求,处理请求并给出响应。并且服务端也会为

    每一个客户端维护一个Session,Session以后会详细介绍。


    MINA服务端处理流程:

    1. IOAcceptor 侦听网络上的链接和包

    2. 针对每一个链接,一个新的session将会被创建,并且随后该 Ip+ 端口上的请求都会被这个session处理

    3. 所有的包从Session处接受后,传送给Filter,Filters 用于修改包内容(如将字节流转换成特定的java bean,增加或删除信息等等),将字节流和java bean业务对象之

        相互转换常常会用到PacketEncoder / Decoder两个类

    4. 最后,转换后的包或对象将由IOHandler来处理


    Session 创建:

    只要有客户端连接到MINA服务端,都会为该链接创建一个Sessiion并在Session存放一些数据。

    传入的消息处理:

    假设一个Session已经被创建,任何传入的消息都将会导致Selector唤醒。


    MINA 客户端体系

    上文已经介绍了MINA结构体系以及服务端体系,现在来介绍下MINA的客户端结构体系。客户端需要连接上服务端,并发送请求和处理应答。



    MINA客户端处理流程:

    1. 客户端首先创建一个IOConnector(MINA 体系中的结构,用于Socket连接),然后绑定到服务端(即连接到服务端的IP和端口)。
    2. 连接建立后,将会创建一个Session并将该session绑定到连接上

    3. 应用程序或客户端向session中写入数据,在经过过滤器链(Filter Chain)转换后,发送给服务端

    4. session接收到从服务端发送过来的数据,经过Filter Chain过滤转换处理后,交由IOHandler去处理


    Simple Tcp Server


    1. 服务端 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 ));
        }
    }
    2. 启动服务端
    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) );
        }
    }

    3. 启动服务端后,可用telnet 127.0.0.1 9123 来测试。

    Simple Tcp Clinent:


    1. IOHandler 省略

    2. 客户端连接到服务端
    public static void main(String[] args) throws Throwable {
        NioSocketConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
    
        if (USE_CUSTOM_CODEC) {
        connector.getFilterChain().addLast("codec",
            new ProtocolCodecFilter(new SumUpProtocolCodecFactory(false)));
        } else {
            connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        }
    
        connector.getFilterChain().addLast("logger", new LoggingFilter());
        connector.setHandler(new ClientSessionHandler(values));
        IoSession session;
    
        for (;;) {
            try {
                ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));
                future.awaitUninterruptibly();
                session = future.getSession();
                break;
            } catch (RuntimeIoException e) {
                System.err.println("Failed to connect.");
                e.printStackTrace();
                Thread.sleep(5000);
            }
        }
    
        // wait until the summation is done
        session.getCloseFuture().awaitUninterruptibly();
        connector.dispose();
    }



    至此,简单介绍了MINA的整体结构,服务端结构,客户端结构及各自的处理流程,下篇将会介绍IOService层。
  • 相关阅读:
    python3.6.3中html页面转化成pdf
    python3 基于zabbix 自动抓取监控图片
    AWS EC2 云服务器 Red Hat Enterprise Linux Server release 7.4 (Maipo) vnc远程连接教程
    python处理两个json根据序号进行一对一组合
    CentOS6.9 内核升级(2.6.32-696.16.1升级到4.4.101-1.el6.el)
    给List分页
    Quartz的学习记录
    Uri
    Android studio 随笔
    android 随笔之 GridLayout
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256975.html
Copyright © 2011-2022 走看看