Netty3 源码分析 - ChannelUpstreamHandler
ChannelUpstreamHandler处理上行的通道事件,并且在流水线中传送事件。这个接口最常用的场景是拦截IO工作现场产生的事件,传输消息或者执行相关的业务逻辑。在大部分情况下,我们是使用SimpleChannelUpstreamHandler 来实现一个具体的upstream handler,因为它为每个事件类型提供了单个的处理方法。大多数情况下ChannelUpstreamHandler 是向上游发送事件,虽然发送下行事件也是允许的(如带外数据)。
// Sending the event upstream (inbound)
void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
...
ctx.sendUpstream(e);
...
}
// Sending the event downstream (outbound)
void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
...
ctx.sendDownstream(new DownstreamMessageEvent(...));
...
}
利用Channels中的辅助方法来产生或发送人为或控制事件是很有用的。状态管理可以看ChannelHandler。
handleUpstream方法会被同一个线程(如一个IO线程)顺序执行,所以一个Handler没有必要担心会在前一个事件没处理完处理一个新的upstream事件。当然这并不是说对于每个Channel有一个专门的线程,有些传输层的IO 线程可以同时服务多个通道(如NIO Channel),某些只能服务一个通道(如OIO模型)。然后,如果增加一个ExecutionHandler 到ChannelPipeline中,行为变化就会依赖于采用的Executor如何分发事件(有待深入)。
接下来看用的最多的SimpleChannelUpstreamHandler。通过源码可以看到,对于不同的事件类型都提供了方法。他会进行向下转型这些接收到的 upstream event,得到更加有意义的子类型,而后调用适当的处理方法。这些方法的名字和在ChannelEvent中对应的事件名字是一样的。在SimpleChannelUpstreamHandler里面的实现都是简单那的向上转发。如果想要一个handler是双向的话,选用SimpleChannelHandler。
覆盖handleUpstream方法后,最后务必要调用super.handleUpstream(ctx, e)使得其他事件处理方法得到正确执行。
public class MyChannelHandler extends SimpleChannelUpstreamHandler {
@Override
public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// Log all channel state changes.
if (e instanceof ChannelStateEvent) {
logger.info("Channel state changed: " + e);
}
super.handleUpstream(ctx, e);
}
}