Mina源码分析

这边遇到一个mina底层的问题,直接调用 session.close(true) session并没有关闭,因为关闭是个异步的过程,在高版本的mina中已经不推荐直接用session.close  推荐用session.closeNow 等方法,不过都是异步的方法
官网说的方法:
 IoSession session = ...; CloseFuture future = session.close(true);  // Wait until the connection is closed future.awaitUninterruptibly();  // Now connection should be closed. assert future.isClosed();

测试的方法是  在服务端messageReceived 里增加debug断点,客户端发送10来条消息,如果第一条消息超时了 调用session.close(true)方法  ,这时候后续的9条消息还是继续处理了,猜测是跟 粘包处理有关系,那10条消息是一起发过来的,从日志上看是同一个线程处理的,应该是这个线程处理完毕所有消息,才能去处理session.close的消息
这里查阅些资料 结合 mina的源码得知
mina的线程处理模型是使用
Mina源码分析
这个类默认使用的是OrderedThreadPoolExecutor
根据mina的文档这么描述的
Mina源码分析
大意就是 mina默认使用的是绑定策略,一个IoSession 会由线程池中的唯一一个线程去处理,保证不会出现乱序的情况。
OrderedThreadPoolExecutor的代码中我们可以看到
Mina源码分析
保存task的队列是放在session的 attribute里。
大概逻辑是这样的:
1.通过事件机制去往队列里添加任务
Mina源码分析
2.线程接受任务不停循环去处理任务
Mina源码分析

回到刚才debug的情况
1.先连发4条消息(mina通过事件机制将4条消息放入队列  worker去循环处理队列,最后调用handle里的方法,发现某条消息异常,调用session.close(true),session.close抛出事件)
2.这时候客户端在发送多个消息,根据测试还是有可能被加入队列
3.session.close抛出事件,sessionClose 事件会被加入队列,后发的消息如果被offer在前面还有可能被执行,应该是代码拦截了sessionClose之后的消息(猜测)
4.当队列里执行到sessionClose消息时候,才会调用handle里的sessionClosed方法。