上一篇博客 Apache MINA (3) NioSocketAcceptor初始化 了解了NioSocketAcceptor的初始化过程,完成了初始化,Acceptor线程被阻塞,处于等待客户端请求到达的状态,通过进一步研究源代码了解Mina处理请求的过程。
当有客户端的请求到达时selector.select()被唤醒
if (selected > 0) {
// We have some connection request, let's process
// them here.
processHandles(selectedHandles());
}
processHandles(selectedHandles())负责处理所有接收到的请求,首先调用了NioSocketAcceptor的accept方法,接受来自客户端的请求,并初始化一个NioSocketSession,并将SocketChannel绑定到NioSession中,指定了处理该NioSession的NioProcesser,IoServices,IoFilterChain等,最后执行
session.getProcessor().add(session);
把session交给SimpleIoProcessorPool处理。
上一篇博客中介绍了SimpleIoProcessorPool的初始化,他初始化了一个无界线程池this.executor = Executors.newCachedThreadPool();并定义了一个cpu+1个NioProcessor绑定到这个executor中,每个NioProcessor中初始化了一个Selector,提供Nio相关的具体实现,如select(),read(),write()等方法
SimpleIoProcessorPool的add(S session)方法首先指定一个处理session的NioProcessor;其中getProcessor(session),该方法会先从session的attributeMap中找有没有指定好的Processor,如果没有,根据sessionId和cpu+1取模取到一个NioProcessor放到attributeMap中。
processor = pool[Math.abs((int) session.getId()) % pool.length];
session.setAttributeIfAbsent(PROCESSOR, processor);
拿到对应的NioProcessor之后再执行NioPorcessor的add(S sission)方法,实现类是在其父类AbstractPollingIoProcessor中,session会被放到一个线程安全的队列newSessions中
private final Queue<S> newSessions = new ConcurrentLinkedQueue<S>();
然后启动processor,执行startupProcessor();
该方法初始化一个AbstractPollingIoProcessor的内部线程类Processor并放到executor中执行
executor.execute(new NamePreservingRunnable(processor, threadName));
processor开始执行,调用NioProcessor的select()方法,然后执行handleNewSessions(),处理newSessions队列中的session,执行addNow()方法,拿到session对应的SelectableChannel,设置为非阻塞的通道,注册通道为OP_READ,准备读取数据,同时为session构建filterChain,然后通知listeners激活创建事件,激活过滤器当前session创建和打开事件。
然后执行process()方法开始读取数据,初始化IoBuffer
IoBuffer buf = IoBuffer.allocate(bufferSize);
调用NioProcessor的read()方法从channel中读取数据到IoBuffer中,这里指定的默认读取方式是读到buffer满或者数据读完然后结束然后调用buf.flip();重置buffer的指针为初始化状态
然后调用责任链激活数据已经读取到
filterChain.fireMessageReceived(buf);
如果数据已经读完,会将当前session放到flushingSessions队列中。
filterChain负责将从chain中读取的byte数据转换成业务需要的数据,如对象,字符串等,从之前Hellow World的例子中看到,为这个责任链添加了一个按行读取数据的filter
chain.addLast("myChain", new ProtocolCodecFilter(new TextLineCodecFactory()));
构造方法中指定了按行处理的数据的encoder和decoder,如果没有读到换行,则将临时数据存到TextLineDecoder的内部类Context中,直到读到换行,将整行放到AbstractProtocolDecoderOutput的消息队列中,如果消息队列不为空,才将转换好的数据传递给下一个filter
Queue<Object> messageQueue = getMessageQueue();
while (!messageQueue.isEmpty()) {
nextFilter.messageReceived(session, messageQueue.poll());
}
这个时候消息进入到对应业务处理的IoHandler的实现类中去完成业务的相关操作,在之前的例子中创建了一个对应的实现类SimpleMinaServerHandler来处理
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String str = (String)message;
// 打印客户端
System.out.println("receive client message : [ " + str +" ]");
// 回写消息给客户端
session.write(count.incrementAndGet());
}
然后再调用session的write方法将处理后的信息回写给客户端
初始化WriteRequest,交给filterChain,执行fireFilterWrite回写数据给客户端
小结:
以上过程描述了一次简单的客户端请求处理的过程,其核心过程如下:
服务端接到客户端的请求,在bind监听端口后,调用startupAcceptor()方法,接收线程Acceptor被唤醒,创建IoSession,构造IoFilter链,将构造好的IoSession提交给IoProcessor来处理。
SimpleIoProcessorPool初始化时创建了一个cpu+1个IoProcessor来负责处处理请求,按照取模的方式找到一个对应的IoProcessor来处理IoSession,IoSession被放到一个newSessions的队列中等待被处理,startupProcessor()唤醒IoProcessor,开始读取数据,通过IoFilter链进行转换处理,最终提供给IoHandlerAdapter处理请求。
借用网上一张经典的图片来描述这个过程:
接下来会再深入研究mina的线程模型。
- 大小: 59.3 KB
分享到:
相关推荐
Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)
深入理解Apache_Mina_(4)----_IoFilter和IoHandler的区别和联系 深入理解Apache_Mina_(5)----_配置Mina的线程模型 深入理解Apache_Mina_(6)----_Java_Nio_ByteBuffer与Mina_ByteBuffer的区别(类图) 相信你们也愿意去...
apache-mina-2.0.7-bin.zip,apache-mina-2.0.7-src.zip,log4j-1.2.17.zip,slf4j-api-1.6.6.jar,slf4j-api-1.6.6-sources.jar,slf4j-log4j12-1.6.6.jar,mina-example-2.0.7.jar,mina-example-2.0.7-sources....
Apache MINA 线程模型配置 Mina配置
收集整理的Apache Mina chm pdf教程和帮助文档
这个是我学的apache mina2.0学习笔记的实例
最近做rfid读写,C#和java都用udp不用厂家的动态库,udp自己写也简单,但是试了一下Apache mina ,接收的不是string,二十byte[] 数组,简单实现了UDP,网上也有例子,但是不是我要的。可用。
apache mina的入门完整学习资料,附加中文参考手册。
apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...
Apache MINA2实用手册 Apache MINA2实用手册
apache mina实例免费下载,有很多实例代码简单易懂欢迎大家下载!
apache mina chm 格式的api帮助文档。
一个Apache MINA使用案例源代码ApacheMina
Apache MINA 2.0 用户指南
最新的Apache Mina v2.0.8 API手册,chm格式,2014年9月下旬制作。
最近一直在看 Mina 的源码,用了 Mina 这么长时间,说实话,现在才开始对 Mina 有了一 些 深刻的理解,关于 Mina 的基本知识的介绍,这里就不多说了,网上已经有很多不错的文 章 都对 Mina 做了较深刻的剖析,现在...
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架
很详细的描述了apache mina 框架,对于那些对于英文不是很懂得人,这简直就是福音啊,哈哈
Linux下面跑基于apache mina开源库的JAVA程序,用maven构建。详细请见http://blog.csdn.net/wuyuxing24/article/details/48500813