• Mina的使用


    参考:http://xinsync.xju.edu.cn/index.php/archives/category/prglang/java/mina

    简单介绍:MINA框架是对java的NIO包的一个封装,简化了NIO程序开发的难度,封装了很多底层的细节,然开发者把精力集中到业务逻辑上来,最近做了一个相关的项目,为了备忘对MINA做一个总结。

    下面这个start方法用来初始化MINA:
    Java代码
    private void start(int port, WebContext ctx)
    throws IOException, InstantiationException
    , IllegalAccessException, ClassNotFoundException {
    //初始化Acceptor
    NioSocketAcceptor acceptor = new NioSocketAcceptor(5);

    java.util.concurrent.Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池
    //加入过滤器(Filter)到Acceptor
    acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
    acceptor.getFilterChain().addLast("codec",
    new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));
    LoggingFilter filter = new LoggingFilter();
    filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);
    filter.setMessageReceivedLogLevel(LogLevel.DEBUG);
    filter.setMessageSentLogLevel(LogLevel.DEBUG);
    filter.setSessionClosedLogLevel(LogLevel.DEBUG);
    filter.setSessionCreatedLogLevel(LogLevel.DEBUG);
    filter.setSessionIdleLogLevel(LogLevel.DEBUG);
    filter.setSessionOpenedLogLevel(LogLevel.DEBUG);
    acceptor.getFilterChain().addLast("logger", filter);

    acceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用

    acceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用
    acceptor.getSessionConfig().setReceiveBufferSize(1024);//设置输入缓冲区的大小
    acceptor.getSessionConfig().setSendBufferSize(10240);//设置输出缓冲区的大小
    //设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出
    acceptor.getSessionConfig().setTcpNoDelay(true);
    //设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝
    acceptor.setBacklog(100);
    acceptor.setDefaultLocalAddress(new InetSocketAddress(port));
    //加入处理器(Handler)到Acceptor
    acceptor.setHandler(new WebHandler());
    acceptor.bind();
    }

    NioSocketAcceptor是MINA的适配器,一切都是从这里开始的。MINA中有个过滤器和处理器的概念,过滤器用来过滤数据,处理器用来处理数据。具体来说MINA的处理模型就是request->过滤器A->过滤器B->处理器->过滤器B->过滤器A->response,这里的request和response类似serlvet的request和response。
    Java代码
    acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
    //加入一个线程池到适配器,这里用的是jdk自带的线程池

    Java代码
    acceptor.getFilterChain().addLast("codec",
    new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));
    //这里是处理逻辑的关键部位,请求的处理都是在WebDecoder类和WebEncoder类中处理,可以明显从命名上看出来一个是用来解码,另一个是用来编码,requet过来后先进入WebDecoder类(实现了ProtocolDecoder接口)进行解码处理,这里可以加入自己的逻辑把传进来的流解码成自己需要的信息。而WebEncoder类(实现了ProtocolEncoder接口)是进行编码,在这个类里面加入自己的逻辑把处理后的信息组装发送给客户端(response)。而在解码和编码过程中WebHandler(扩展了IoHandlerAdapter抽象类)起到了处理器的作用。
    //request->WebDecoder->WebHandler->WebEncode->response



    现在详细描述一下request->WebDecoder->WebHandler->WebEncode->response的过程:

    客户端发送一个请求到MINA服务器,这里相当于来了一个requet。请求首先来到
    Java代码
    WebDecoder类(实现了ProtocolDecoder接口)中的
    boolean decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception{}方法


    然后到
    Java代码
    WebHandler(扩展了IoHandlerAdapter抽象类)中的
    void messageReceived(IoSession session, Object message) throws Exception{}方法
    WriteFuture future = session.write(response);//session中必须加入这个代码,才会激活encode方法
    future.addListener(IoFutureListener.CLOSE);//这个的作用是发送完毕后关闭连接,加了就是短连接,不然是长连接
    IoFutureListener里面有个operationComplete(IoFuture future)方法,当流发送完成之后才调用这个方法。



    然后到
    Java代码
    WebEncoder类(实现了ProtocolEncoder接口)中的
    boolean encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception{}
    方法

  • 相关阅读:
    SQLServer提取日期中的年月日及其他格式
    大白话解说,半分钟就懂 --- 分布式与集群是什么 ? 区别是什么?
    VS2015 Git 源码管理工具简单入门
    Web.Config配置文件中customErrors元素的使用方法
    C#发起Http请求,调用接口
    如何停止和禁用Linux系统中的不需要的服务
    QtCreator调试传入运行参数
    gSOAP 在windows下的安装与使用(mingw32)
    MinGW 使用 mintty 终端替代默认终端以解决界面上复制与粘贴的问题
    在windows下执行./configure,make,makeinstall源码安装程序spice-gtk
  • 原文地址:https://www.cnblogs.com/suifengbingzhu/p/2648302.html
Copyright © 2020-2023  润新知