`
assertmyself
  • 浏览: 29591 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

MINA 笔记

阅读更多

关于mina
     跟netty类似,java的网络层IO处理框架,提供高并发的网络编程框架
例子参考:
     入门例子:org.apache.mina.example.gettingstarted.timeserver.MinaTimeServer  telnet服务器例子。
  TCP例子:org.apache.mina.example.sumup.Server/Client 数值运算
  UDP例子:org.apache.mina.example.udp.MemoryMonitor/cient


高级特性:
     IoService:所有 IO 服务的基类,不管是在服务器端还是在客户端。它将处理所有与你的应用之间的交互,以及与远程对端的交互,发送并接收消息、管理session、管理连接等等。它是为一个接口,服务器端实现为 IoAcceptor,客户端为 IoConnector
            1.session 管理:创建和删除 session,检测闲置 session
            2.过滤器链管理:操纵过滤器链,允许用户运行中改变过滤器链
            3.处理器调用:接收到新消息时调用处理器,等等
            4.统计管理:更新发送消息的数量、发送字节的数量,等等
            5.监听器管理:管理用户创建的监听器
            6.通信管理:在服务器端和服务器端处理传输的数据
            7.两个最主要的实现IoAcceptor  IoConnector

     IoAcceptor:,IoAcceptor 接口是因为 accept() 方法的缘故所命名,用于服务器编码,常见实现类
            1.NioSocketAcceptor:非阻塞套接字传输 IoAcceptor
            2.NioDatagramAcceptor:非阻塞 UDP 传输 IoAcceptor
            3.AprSocketAcceptor:基于 APR 的阻塞套接字传输 IoAcceptor
            4.VmPipeSocketAcceptor:in-VM IoAcceptor

     IoConnector:客户端编码实现,,因为socket经常用到connect方法链接服务器
            1.NioSocketConnector:非阻塞套接字传输 IoConnector
            2.NioDatagramConnector:非阻塞 UDP 传输 IoConnector
            3:AprSocketConnector:基于 APR 的阻塞套接字传输 IoConnector
            4.ProxyConnector:一个提供代理支持的 IoConnector
            5.SerialConnector:一个用于串行传输的 IoConnector
            6.VmPipeConnector:in-VM IoConnector
    

Session:Session(会话)是 MINA 的核心。每当一个客户端连接到服务器,一个新的会话会被创建,并会在客户端关掉连接前一直保存在内存中。因此可以做为状态维护,解决很多无状态的问题。
     状态:
            1.connected:会话已被创建并可用
            2.idle:会话在至少一段时间 (这段时间是可配的) 内没有处理任何请求
            3.closing:会话正在关闭中 (还有正在清空的消息,清理尚未结束)
            4.closed:会话现在已被关闭,没有其他方法可以将其恢
     应用:自定义属性,会话用于保存连接的持久信息,以及在请求处理过程中、会话的生命周期中服务器可能需要用到的任何信息。
            int counterValue = session.getAttribute( "counter" );
            session.setAttribute( "counter", counterValue + 1 );

           
Filter:过滤器:过滤 IoService 和 IoHandler 之间的所有 I/O 事件和请求,
     常用的过滤器
            1.LoggingFilter记录所有事件和请求
                   MINA 使用了 Simple Logging Facade for Java(SLF4J),SLF4J选择合适的 JAR 包,下面的日志框架|所需要的jar
                         1.Log4J 1.2.x |  slf4j-api.jar, slf4j-log4j12.jar**
                         2.Log4J 1.3.x  | slf4j-api.jar, slf4j-log4j13.jar
                         3.java.util.logging | slf4j-api.jar, slf4j-jdk14.jar**
                         4.Commons Logging | slf4j-api.jar, slf4j-jcl.jar
            2.ProtocolCodecFilter 将一个连入的 ByteBuffer 转化为消息 POJO,反之亦然
                   为什么需要编解码filter?
                         1如果没有ProtocolCodecFilter 的话,一个由发送端对 IoSession.write(Object message) 的调用将导致多个接收端的 messageReceived(IoSession session, Object message) 事件,而多个 IoSession.write(Object message) 的调用只会引起唯一的一个 messageReceived 事件。
                         2大多数网络应用需要一种方法以找出当前消息的结束位置和下一条消息的起始位置
                         3完全可以在你的 IoHandler 实现所有的这些逻辑,但是添加一个 ProtocolCodecFilter可以让你的代码更加清晰并容易维护
                         4它将你的协议逻辑从你的业务逻辑中 (IoHandler) 剥离开来
                   如何使用?
                         1.使用固定长度的字节编码
                         2.使用固定长度的报头来指示出报体的长度
                         3.使用定界符。例如,许多基于文本的协议在每条消息
                        
            3.CompressionFilter 压缩所有数据
            4.SSLFilter 添加 SSL - TLS - StartTLS 支持
     重写:
            public class MyFilter extends IoFilterAdapter {
              @Override
              public void sessionOpened(NextFilter nextFilter, IoSession session) throws Excepti
              on {
              // Some logic here...
              nextFilter.sessionOpened(session);
              // Some other logic here...
              }
              }
    

IOHandler: IO处理器,个会话会被附加到一个处理器,该处理器负责调度给你的应用的消息。这个处理器也会通过使用会话发送响应包,只需调用 write() 方法:例如session.write( <your message> );
     常用方法:
            1.sessionCreated:会话建立事件在一个新的连接被创建时触发,对于 TCP 来说这是连接接受的结果,而对于UDP 这个在接收到一个 UDP 包时产生。这一方法可以被用于初始化会话属性,并为一些特定连接执行一次性活动。
            2.sessionOpened:会话打开事件是在一个连接被打开时调用,它总是在 sessionCreated 事件之后调用。如果配置了一个线程模型,这一方法将在 I/O 处理线程之外的一个线程中调
            3.sessionClosed:会话关闭事件在会话被关闭时调用。会话清理活动比如清理支付信息可以在这里执行。
            4.sessionIdle:会话空闲时间在会话变为闲置状态时触发。这一方法并不为基于 UDP 的传输调用
            5.exceptionCaught:这一方法在用户代码或者 MINA 抛异常时调用。链接将关闭
            6.messageReceived:消息接收事件在一个消息被接收到时触发。这是一个应用最常发生的处理
            7.messageSent:消息发送事件在消息响应被发送 (调用 IoSession.write()) 时触发


IoBuffer
     MINA 应用所用的一个字节缓存。它用于替代 ByteBuffer。MINA 不直接使用 NIO 的 ByteBuffer
     操作:
            1.IoBuffer是个抽象类,因此不能够直接被实例化。要分配 IoBuffer,我们需要使用两个allocate() 方法中的其中一个。
            1.1 public static IoBuffer allocate(int capacity, boolean direct)和
            1.2 public static IoBuffer allocate(int capacity)
           






     服务器应用
服务的创建和销毁
            1.创建,,new IOAcceptor
            2.销毁 ,, acceptor.dispose();//默认服务只能在所有等待中的 session 都被处理之后,设置为true 立即执行
            3.IoService的状态相关函数:isActive(),isDisposing(),isDisposed()
            4.管理 IoHandler:当服务实例化之后你可以添加或者获取其关联到的 IoHandler。你只需要去调用一把setHandler(IoHandler) 或者 getHandler() 方法。
            5.管理过滤器链:acceptor.getFilterChain().addLast("logger", new LoggingFilter())
     客户端应用:
            1.实现一个 IoConnector 接口的实现
            2.其它流程参考服务应用


APR应用:
     APR (Apache Portable Runtime) 提供了更好的扩展性、性能以及更好的与本地服务器技术的集成。MINA 照常 APR 传输。现
  应用:IoAcceptor acceptor = new NioSocketAcceptor();改为IoAcceptor acceptor = new AprSocketAcceptor();


串行应用:
     使用 MINA 2.0 你可以连接到串行端口,就像你使用 MINA 连接到一个 TCP/IP 端口一样
            需要使用mina-transport-serial以及只需要把合适的 .dll 或者 .so 放在你的 JDK/JRE 的 jre/lib/i386/ 目录
     应用举例:
            1.你需要一个 SerialConnector 以连接到一个串行端口:,除了 SocketConnector 之外没啥不同的
             // create your connector
             IoConnector connector = new SerialConnector()
             connector.setHandler( ... here your buisness logic IoHandler ... );
            2.创建串口地址
                   SerialAddress portAddress=new SerialAddress( "/dev/ttyS0", 38400, 8, StopBits.BITS_1,Parity.NONE, FlowControl.NONE );//第一个参数是你的端口标识。对于 Windows 系统的电脑,串行端口被叫做"COM1"、"COM2" 等等...对于 Linux 和其他 Unix 系统:"/dev/ttyS0"、"/dev/ttyS1"、"/dev/ttyUSB0"。
            3.,将连接器连接到相应地址
                   ConnectFuture future = connector.connect( portAddress );
                   future.await();
                   IoSession sessin = future.getSession();








代码示例:详细参考


Server:
       private static final Logger logger =Logger.getLogger(Server.class);
    private static final int SERVER_PORT = 8080;
    // Set this to false to use object serialization instead of custom codec.
    private static final boolean USE_CUSTOM_CODEC = true;
    public static void main(String[] args) throws Throwable {
        NioSocketAcceptor acceptor = new NioSocketAcceptor(); //创建一个IOservice  也就是接收器
        // Prepare the service configuration.
        if (USE_CUSTOM_CODEC) { //添加filter-chains
            acceptor.getFilterChain()
                    .addLast(
                            "codec",
                            new ProtocolCodecFilter(
                                    new SumUpProtocolCodecFactory(true)));
        } else {
            acceptor.getFilterChain().addLast(
                    "codec",
                    new ProtocolCodecFilter(
                            new ObjectSerializationCodecFactory()));
        }
        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        acceptor.setHandler(new ServerSessionHandler()); //服务器IO handler
        acceptor.bind(new InetSocketAddress(SERVER_PORT)); //绑定,异步
        System.out.println("Listening on port " + SERVER_PORT);
        logger.error("the service ok !!!");
    }



如果需要UDP服务,,仅需要修改 IOAcceptor代码
例如:
       
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();//创建一个Datagrame的 接收器
        acceptor.setHandler(new MemoryMonitorHandler(this));//添加IOhandler,,个 IoHandler 以处理 MINA 框架生成的事件
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        chain.addLast("logger", new LoggingFilter());//添加日志filter
        DatagramSessionConfig dcfg = acceptor.getSessionConfig();//添加session配置
        dcfg.setReuseAddress(true);//配置,地址重用接下来我们来看一些更具体的 UDP 传输的代码。我们设置 acceptor 以复




客户端:
       
//if (args.length == 0) {
         //   System.out.println("Please specify the list of any integers");
          //  return;
        //}
        // prepare values to sum up
//        int[] values = new int[args.length];
        int [] values = new int[]{1,2,3,5};
        for (int i = 0; i < args.length; i++) {
            values[i] = Integer.parseInt(args[i]);
        }
        NioSocketConnector connector = new NioSocketConnector();//创建一个 connector 不是acceptor 我们已经创建了一个 NIO Socket 连接器
        // Configure the service.
        connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
        if (USE_CUSTOM_CODEC) {
            connector.getFilterChain().addLast( //创建一个 filter-chains
                    "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)); //创建一个IOHandler 并添加到 connector;;这里我们创建了一个 ClientSessionHandler 的实例并将其设置为 Connector 的处理器
        IoSession session;
        for (;;) {
            try {
                ConnectFuture future = connector.connect(new InetSocketAddress(
                        HOSTNAME, PORT));//这是最重要的部分。我们将连接到远程服务器。因为是异步连接任务,我们使用了
                //ConnectFuture 来了解何时连接完成。一旦连接完成,我们将得到相关联的 IoSession。要向
               // 服务器端发送任何消息,我们都要写入 session。所有来自服务器端的响应或者消息都将穿越
               // Filter chain 并最终由 IoHandler 处理。
                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
       
        for(int i = 0;i<5;i++){
            AddMessage m = new AddMessage();
            m.setSequence(i);
            m.setValue( i+6 );
//            WriteFuture wf  =session.write( i+6 ); // 发送 错误编码,会有异常,但不报错,,失败
              WriteFuture wf  =session.write(m); // 发送
              wf.addListener(new IoFutureListener<IoFuture>() {
                           public void operationComplete(IoFuture future) {
                                  // TODO Auto-generated method stub
                                  System.out.println("send ok +" );
                                  //+future.getSession().write("hell")
                           }
                     });
        }
       
       
        session.getCloseFuture().awaitUninterruptibly();//调用session关闭命令,,
       
        connector.dispose();//断开

  

UDP客户端:

      
 LOGGER.debug("UDPClient::UDPClient");
        LOGGER.debug("Created a datagram connector");
        connector = new NioDatagramConnector();//connector 客户端 们创建了一个 NioDatagramConnector,设置了处理器然后连接到服务器。
        LOGGER.debug("Setting the handler");
        connector.setHandler(this);
        LOGGER.debug("About to connect to the server...");
        ConnectFuture connFuture = connector.connect(new InetSocketAddress( //链接到指定的服务器
                "localhost", MemoryMonitor.PORT));
        LOGGER.debug("About to wait.");
        connFuture.awaitUninterruptibly();//conect是异步,该处 同步等待 建联完成
        LOGGER.debug("Adding a future listener.");
        connFuture.addListener(new IoFutureListener<ConnectFuture>() { //一旦得知我们已经建立连接,我们就可以开始向服务器端写数据了:
            public void operationComplete(ConnectFuture future) {
                if (future.isConnected()) {
                    LOGGER.debug("...connected");
                    session = future.getSession();
                    try {
                        sendData();//30s发送数据
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    LOGGER.error("Not connected...exiting");
                }
            }
        });

  
抛开独自的业务不讲,,代码接口是统一的,,仅选择合适的实现类即可



分享到:
评论

相关推荐

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    MIna2.0学习笔记

    Apache Mina是一个高性能、异步事件驱动的网络应用程序框架,主要用在开发网络通信应用,如TCP/IP和UDP协议的应用。Mina2.0作为其更新版本,提供了更丰富的功能和优化的性能,使得开发者能更高效地构建网络服务。 *...

    Mina学习笔记

    Apache Mina是一个基于Java的网络通信框架,专为高性能、高可用性和可扩展性而设计。这个框架使得开发者能够轻松地构建网络应用,如TCP/IP和UDP协议的服务器和客户端。下面将详细介绍Mina的基本概念、核心接口以及...

    mina学习笔记,记录所有API

    在MINA的学习笔记中,记录的所有API通常会包括以下几个核心部分: 1. **IoSession**: 这是MINA的核心接口,代表了客户端和服务器之间的连接。IoSession提供了读写数据、管理连接状态、获取会话属性等功能。例如,`...

    Mina2.0学习笔记(修订版).

    Apache Mina是一个高性能、事件驱动的网络应用框架,主要用于简化开发服务器端的复杂性,尤其在处理TCP/IP、UDP和SSL/TLS等协议时。它提供了丰富的API和工具,使得开发者能够快速构建网络应用程序,如FTP、SMTP、...

    Mina2.0学习笔记(完整版).doc

    Apache Mina是一个强大的开源框架,专门用于构建高性能、高可扩展性的网络应用程序。Mina2.0是其一个重要的版本,提供了许多改进和新特性,使得开发者能够更轻松地处理网络通信任务,尤其是在Java NIO(Non-blocking...

    Apache mina2学习笔记DEMO

    在这个"Apache MINA2学习笔记DEMO"中,我们很可能会看到如何使用MINA来创建一个自定义协议的示例。自定义协议通常是为了满足特定应用的需求,例如高效的数据传输、安全性或者特定的编码格式。MINA允许开发者定义自己...

    Mina2.0学习笔记(修订版)

    ### Mina2.0学习笔记核心知识点概览 #### 一、Mina入门与环境搭建 **Mina简介** Mina是Apache旗下的一款强大的网络应用框架,专为高性能和高可扩展性网络应用设计,其核心是利用Java NIO技术提供事件驱动的异步API...

    资料_MINA(2、3、4).rar

    MINA笔记.docx MINA2官方教程翻译.pdf Mina2.0快速入门与源码剖析.pdf MINA网络框架和RMI的对比研究.pdf 基于3G网络的移动流媒体服务器的设计与实现.pdf 高性能通信框架及智能主站技术研究.nh MINA类图.doc 等

    apache mina 学习笔记三(子项目FtpServer)

    在本学习笔记中,我们将专注于MINA的子项目——FtpServer,它是实现FTP服务器功能的一个模块。 FTP(File Transfer Protocol)是一种广泛使用的互联网协议,用于在不同主机之间传输文件。Apache MINA FtpServer提供...

    mina初步学习笔记

    ### Mina初步学习笔记知识点概览 #### 一、Mina简介及下载配置流程 **Mina**,全称**Multipurpose Infrastructure Networked Applications**,是Apache基金会开发的一个高性能网络应用框架,旨在帮助开发者构建高...

    mina学习笔记

    《mina学习笔记》 Apache MINA(Multipurpose Infrastructure for Network Applications)是一个开源框架,主要设计用于简化网络应用程序的开发,尤其是TCP和UDP协议的应用。MINA 提供了一种与网络协议无关的API,...

    Mina 学习笔记(入门)

    **Mina 学习笔记(入门)** Apache Mina 是一个高度可扩展的网络通信框架,主要用于构建高性能、高效率的服务器端应用。它提供了一种简单的方式来处理网络协议,如TCP/IP和UDP/IP,以及SSL/TLS加密的连接。在本学习...

    Apache_Mina2.0学习笔记

    最近使用Mina开发一个Java的NIO服务端程序,因此也特意学习了Apache的这个Mina框架。 引言 1 一. Mina入门 2 第一步.下载使用的Jar包 2 第二步.工程创建配置 2 第三步.服务端程序 3 第四步.客户端程序 6 第五步.长...

    MINA学习笔记(仅供参考)

    ### MINA学习笔记 #### MINA概述 MINA是一个用Java编写的高性能、轻量级的网络通信框架,主要用于简化网络编程的复杂性。它支持多种传输协议(如TCP/IP和UDP/IP),并且提供了一套丰富的API来处理网络通信相关的...

Global site tag (gtag.js) - Google Analytics