您的位置:首页 > 运维架构 > Apache

Apache MINA学习笔记

2016-01-12 18:08 543 查看
Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。

先看看MINA的架构图



IoService 是负责底层通讯接入,而 IoHandler 是负责业务处理的。那么 MINA 架构图中的 IoFilter 作何用途呢?答案是你想作何用途都可以。但是有一个用途却是必须的,那就是作为 IoService 和 IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceived,这个方法的第二个参数是一个 Object 型的消息,总所周知,Object 是所有 Java 对象的基础,那到底谁来决定这个消息到底是什么类型呢?答案也就在这个 IoFilter
中。在前面使用的例子中,我们添加了一个 IoFilter 是 new ProtocolCodecFilter(new TextLineCodecFactory()),这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给 IoHandler,因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。

而如果我们不提供任何过滤器的话,那么在 messageReceived 方法中的第二个参数类型就是一个 byte 的缓冲区,对应的类是 org.apache.mina.core.buffer.IoBuffer。虽然你也可以将解析客户端信息放在 IoHandler 中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得 IoHandler 不只是业务处理,还得充当协议解析的任务。

MINA自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilter(SSL加密)等。

简单地来讲,就分为三层:

1)I/O Service :负责处理I/O。

2)I/O Filter Chain :负责编码处理,字节到数据结构或数据结构到字节的转换等,即非业务逻辑的操作。

3)I/O Handle :负责处理业务逻辑。

客户端的通信过程:

1)通过SocketConnector同服务器端建立连接。

2)链接建立之后I/O的读写交给了I/O Processor线程,I/O Processor是多线程的。

3)通过I/O Processor读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议。

4)最后IoFilter将数据交给Handler进行业务处理,完成了整个读取的过程。

5)写入过程也是类似,只是刚好倒过来,通过IoSession.write写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过I/O Processor将数据写出到socket通道。

IoFilterChain作为消息过滤链

1)读取的时候是从低级协议到高级协议的过程,一般来说从byte字节逐渐转换成业务对象的过程。

2)写入的时候一般是从业务对象到字节byte的过程。



MINA服务器

public class MinaServer {

// 定义监听端口
private static final int PORT = 6488;

public static void main(String[] args) throws Exception {
// 创建服务端监控线程
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 ServerHandler());
// 设置端口号
acceptor.bind(new InetSocketAddress(PORT));
// 启动监听线程
acceptor.bind();
}
}
服务端的IO Handler

public class ServerHandler extends IoHandlerAdapter {

@Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println(session.getRemoteAddress().toString());
}

@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String msg = message.toString();
if(msg.trim().equalsIgnoreCase("quit")) {
session.close(true);
return;
}
session.write("got it!");
System.out.println(msg);
}

@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("IDLE" + session.getIdleCount(status));
}

}
MINA客户端

public class MinaClient {
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 ClientHandler());

// 建立连接
ConnectFuture cf = connector.connect(new InetSocketAddress("127.0.0.1", 6488));
// 等待连接创建完成
cf.awaitUninterruptibly();

cf.getSession().write("Hi Server!");
cf.getSession().write("quit");

// 等待连接断开
cf.getSession().getCloseFuture().awaitUninterruptibly();
// 释放连接
connector.dispose();
}
}
客户端的IO Handler

public class ClientHandler extends IoHandlerAdapter {

@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String content = message.toString();
System.out.println("client receive a message is : " + content);
}

@Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("messageSent -> :" + message);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: