在apache mina中,IoFilterChain是与业务逻辑关联最紧密的。在IoFiterChain接口中与业务相关的是以fireXXX()开头的方法。
// A container of IoFilters that forwards IoHandler events to the consisting filters and terminal IoHandler sequentially.
// Every IoSession has its own IoFilterChain (1-to-1 relationship).
public interface IoFilterChain
{
public void fireSessionCreated();
public void fireSessionOpened();
public void fireSessionClosed();
public void fireSessionIdle(IdleStatus status);
public void fireMessageReceived(Object message);
public void fireMessageSent(WriteRequest request);
public void fireExceptionCaught(Throwable cause);
public void fireInputClosed();
public void fireFilterWrite(WriteRequest writeRequest);
public void fireFilterClose();
}
1-IoSession 的create、opened事件。opened事件流程与create事件流程完全一致。
在IoProcessor线程中,触发SessionCreate事件,堆栈如下:
IoServiceListenerSupport.fireSessionCreated(IoSession)
NioProcessor(AbstractPollingIoProcessor<S>).addNow(S)
NioProcessor(AbstractPollingIoProcessor<S>).handleNewSessions()
在IoServiceListenerSupport.fireSessionCreated(IoSession) 方法中,先分发了create事件,紧接着触发了open事件。
// Fire session events.
IoFilterChain filterChain = session.getFilterChain();
filterChain.fireSessionCreated();
filterChain.fireSessionOpened();
在DefaultIoFilterChain.fireSessionCreated() 过滤链中,create事件从HeadFilter过滤链从头开始分发,直到TailFilter 过滤链中。在整个过滤链中的每一个sessionCreated都被触发。在TailFilter 过滤链中会触发IoHandler中的sessionCreated事件。
private static class TailFilter extends IoFilterAdapter {
@Override
public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
try {
session.getHandler().sessionCreated(session);
} finally {
// Notify the related future.
ConnectFuture future = (ConnectFuture) session.removeAttribute(SESSION_CREATED_FUTURE);
if (future != null) {
future.setSession(session);
}
}
}
}
其中在sessioncreate事件中,涉及ConnectFuture 模式。
protected final void initSession(IoSession session, IoFuture future, IoSessionInitializer sessionInitializer) {
if ((future != null) && (future instanceof ConnectFuture)) {
// DefaultIoFilterChain will notify the future. (We support ConnectFuture only for now).
session.setAttribute(DefaultIoFilterChain.SESSION_CREATED_FUTURE, future);
}
}
在AbstractIoService 初始化IoSession时,会创建一个ConnectFuture,在TailFilter中会设置ConnectFuture的完成。
private static class TailFilter extends IoFilterAdapter {
@Override
public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
try {
session.getHandler().sessionCreated(session);
} finally {
// Notify the related future.
ConnectFuture future = (ConnectFuture) session.removeAttribute(SESSION_CREATED_FUTURE);
//设置future完成状态
if (future != null) {
future.setSession(session);
}
}
}
}
2- IoSession Received事件
DefaultIoFilterChain.fireMessageReceived(Object)
NioProcessor(AbstractPollingIoProcessor<S>).read(S)
NioProcessor(AbstractPollingIoProcessor<S>).process(S)
NioProcessor(AbstractPollingIoProcessor<S>).process()
在IoProcessor线程中触发Received事件。同时在IoProcessor线程中统计读取数据的统计。
public void fireMessageReceived(Object message) {
if (message instanceof IoBuffer) {
session.increaseReadBytes(((IoBuffer) message).remaining(), System.currentTimeMillis());
}
//统计IoSession对于数据的读取统计,并从HeadFilter开始分发Received事件
callNextMessageReceived(head, session, message);
}
IoSession Received整个流程也是从HeadFilter开始,在TailFilter调用IoHandler处理业务逻辑。但是在TailFilter中也会处理apache mina本身的业务逻辑统计。
private static class TailFilter extends IoFilterAdapter {
@Override
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
if (!(message instanceof IoBuffer)) {
s.increaseReadMessages(System.currentTimeMillis());
} else if (!((IoBuffer) message).hasRemaining()) {
s.increaseReadMessages(System.currentTimeMillis());
}
// Update the statistics
if (session.getService() instanceof AbstractIoService) {
((AbstractIoService) session.getService()).getStatistics().updateThroughput(System.currentTimeMillis());
}
// Propagate the message
try {
session.getHandler().messageReceived(s, message);
} finally {
if (s.getConfig().isUseReadOperation()) {
s.offerReadFuture(message);
}
}
}
}
3 -IoSession Write 事件
Write事件也是在IoProcessor线程中触发。Write事件也是从HeadFilter到TailFilter顺序来写入数据。
DefaultIoFilterChain.fireMessageSent(WriteRequest)
NioProcessor(AbstractPollingIoProcessor<S>).fireMessageSent(S, WriteRequest)
NioProcessor(AbstractPollingIoProcessor<S>).writeBuffer(S, WriteRequest, boolean, int, long)
NioProcessor(AbstractPollingIoProcessor<S>).flushNow(S, long)
NioProcessor(AbstractPollingIoProcessor<S>).flush(long)
AbstractPollingIoProcessor<S>.access$11(AbstractPollingIoProcessor, long)
AbstractPollingIoProcessor$Processor.run()
NamePreservingRunnable.run()
ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker)
ThreadPoolExecutor$Worker.run()
在TailFilter也会对apache mina本身业务逻辑进行处理,然后调用IoHandler中的send方法。