Mina 学习笔记

来源:互联网 发布:阿里云总裁 编辑:程序博客网 时间:2024/06/01 07:42

1.概述

ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。

2.Mina几个重要接口:

IoServiece :这个接口在一个线程上负责套接字的建立,拥有自己的 Selector,监听是否有连接被建立。
IoProcessor :这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是说它也拥有自己的 Selector,这是与我们使用 JAVA NIO 编码时的一个不同之处,通常在 JAVA NIO 编码中,我们都是使用一个 Selector,也就是不区分 IoService与 IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在 IoService 上的过滤器,并在过滤器链之后调用 IoHandler。
IoAccepter :相当于网络应用程序中的服务器端
IoConnector :相当于客户端
IoSession :当前客户端到服务器端的一个连接实例
IoHandler :这个接口负责编写业务逻辑,也就是接收、发送数据的地方。这也是实际开发过程中需要用户自己编写的部分代码。
IoFilter :过滤器用于悬接通讯层接口与业务层接口,这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的 encode与 decode是最为重要的、也是你在使用 Mina时最主要关注的地方。

3.IO分为三层

1.IO Service :负责处理IO。
2.IO Fiter Chain :处理编码,字节到数据结构或数据结构到字节的转换等,即非业务逻辑的操作。
3.IO Handle : 负责处理业务逻辑。

4.客户端的通信过程:

1.通过SocketConnector同服务器建立连接。
2.连接建立之后IO的读写交给了IO Processor线程,IO Processor是多线程的。
3.通过IO Processor读取的数据经过IO FiterChain 里所有配置的IO Filter 进行消息的过滤,格式的转换,在这个层面上可以定制一些自定义的协议。
4.最后IO Filter 将数据交给Handle进行业务处理,完成了整个读取的过程。
5.写入的过程也是类似,只是刚好倒过来,通过IOSession.write写出数据,然后Handler完成后交给IO FilterChain ,进行消息过滤和协议的转换,最后通过IO Processor 将数据写出到socket通道。

5.MINA框架进行开发

首先定义一个业务逻辑处理器TimeServerHandler,继承自IoHandlerAdapter,实现的功能有:当客户端创建会话时会显示客户端设备的IP和端口;当客户端输入quit时结束会话;客户端输入其它内容时则向客户端发送当前时间。
创建服务器:

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 = 6488;    public static void main(String[] args) throws IOException {        // 创建服务端监控线程        IoAcceptor acceptor = new NioSocketAcceptor();        acceptor.getSessionConfig().setReadBufferSize(2048);        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);        // 设置日志记录器        acceptor.getFilterChain().addLast("logger", new LoggingFilter());        // 设置编码过滤器        acceptor.getFilterChain().addLast(            "codec",            new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));        // 指定业务逻辑处理器        acceptor.setHandler(new TimeServerHandler());        // 设置端口号        acceptor.bind(new InetSocketAddress(PORT));        // 启动监听线程        acceptor.bind();    }}

服务器端业务逻辑

import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;/** * 服务器端业务逻辑 */public class TimeServerHandler extends IoHandlerAdapter {    /**     * 连接创建事件     */    @Override    public void sessionCreated(IoSession session){        // 显示客户端的ip和端口        System.out.println(session.getRemoteAddress().toString());    }    @Override    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {        cause.printStackTrace();    }    /**     * 消息接收事件     */    @Override    public void messageReceived(IoSession session, Object message) throws Exception {        String strMsg = message.toString();        if (strMsg.trim().equalsIgnoreCase("quit")) {            session.close(true);            return;        }        // 返回消息字符串        session.write("Hi Client!");        // 打印客户端传来的消息内容        System.out.println("Message written : " + strMsg);    }    @Override    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {        System.out.println("IDLE" + session.getIdleCount(status));    }}

客户端:

import java.net.InetSocketAddress;import java.nio.charset.Charset;import org.apache.mina.core.future.ConnectFuture;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.NioSocketConnector;public class MinaTimeClient {    public static void main(String[] args){        // 创建客户端连接器.        NioSocketConnector connector = new NioSocketConnector();        connector.getFilterChain().addLast("logger", new LoggingFilter());        connector.getFilterChain().addLast("codec",                new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));        // 设置连接超时检查时间        connector.setConnectTimeoutCheckInterval(30);        connector.setHandler(new TimeClientHandler());        // 建立连接        ConnectFuture cf = connector.connect(new InetSocketAddress("192.168.2.109", 6488));        // 等待连接创建完成        cf.awaitUninterruptibly();        cf.getSession().write("Hi Server!");        cf.getSession().write("quit");        // 等待连接断开        cf.getSession().getCloseFuture().awaitUninterruptibly();        // 释放连接        connector.dispose();    }}

客户端处理逻辑:

import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;public class TimeClientHandler extends IoHandlerAdapter {    public void messageReceived(IoSession session, Object message) throws Exception {        String content = message.toString();        System.out.println("client receive a message is : " + content);    }    public void messageSent(IoSession session, Object message) throws Exception {        System.out.println("messageSent -> :" + message);    }}

总结:
MINA框架完成了底层的线程管理和socket管理;MINA内置的编码器可以满足大多数用户的需求,省去了开发人员消息编码解码的工作。建议在网络应用程序开发过程中尝试使用MINA框架来提高我们的开发效率和应用程序的执行效率。

原创粉丝点击