找回密码
 立即注册
首页 业界区 业界 Netty源码—5.Pipeline和Handler

Netty源码—5.Pipeline和Handler

能杜孱 2025-6-3 14:18:27
大纲
1.Pipeline和Handler的作用和构成
2.ChannelHandler的分类
3.几个特殊的ChannelHandler
4.ChannelHandler的生命周期
5.ChannelPipeline的事件处理
6.关于ChannelPipeline的问题整理
7.ChannelPipeline主要包括三部分内容
8.ChannelPipeline的初始化
9.ChannelPipeline添加ChannelHandler
10.ChannelPipeline删除ChannelHandler
11.Inbound事件的传播
12.Outbound事件的传播
13.ChannelPipeline中异常的传播
14.ChannelPipeline总结
 
1.Pipeline和Handler的作用和构成
(1)Pipeline和Handler的作用
(2)Pipeline和Handler的构成
 
(1)Pipeline和Handler的作用
可以在处理复杂的业务逻辑时避免if else的泛滥,可以实现对业务逻辑的模块化处理,不同的逻辑放置到单独的类中进行处理。最后将这些逻辑串联起来,形成一个完整的逻辑处理链。
 
Netty通过责任链模式来组织代码逻辑,能够支持逻辑的动态添加和删除,能够支持各类协议的扩展。
 
(2)Pipeline和Handler的构成
在Netty里,一个连接对应着一个Channel。这个Channel的所有处理逻辑都在一个叫ChannelPipeline的对象里,ChannelPipeline是双向链表结构,它和Channel之间是一对一的关系。
 
ChannelPipeline里的每个结点都是一个ChannelHandlerContext对象,这个ChannelHandlerContext对象能够获得和Channel相关的所有上下文信息。每个ChannelHandlerContext对象都包含一个逻辑处理器ChannelHandler,每个逻辑处理器ChannelHandler都处理一块独立的逻辑。
 
2.ChannelHandler的分类
ChannelHandler有两大子接口,分别为Inbound和Outbound类型:第一个子接口是ChannelInboundHandler,用于处理读数据逻辑,最重要的方法是channelRead()。第二个子接口是ChannelOutboundHandler,用于处理写数据逻辑,最重要的方法是write()。
 
这两个子接口默认的实现分别是:ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter。它们分别实现了两个子接口的所有功能,在默认情况下会把读写事件传播到下一个Handler。
 
InboundHandler的事件通常只会传播到下一个InboundHandler,OutboundHandler的事件通常只会传播到下一个OuboundHandler,InboundHandler的执行顺序与实际addLast的添加顺序相同,OutboundHandler的执行顺序与实际addLast的添加顺序相反。
 
Inbound事件通常由IO线程触发,如TCP链路的建立事件、关闭事件、读事件、异常通知事件等。其触发方法一般带有fire字眼,如下所示:
ctx.fireChannelRegister()、
ctx.fireChannelActive()、
ctx.fireChannelRead()、
ctx.fireChannelReadComplete()、
ctx.fireChannelInactive()。
 
Outbound事件通常由用户主动发起的网络IO操作触发,如用户发起的连接操作、绑定操作、消息发送等操作。其触发方法一般如:ctx.bind()、ctx.connect()、ctx.write()、ctx.flush()、ctx.read()、ctx.disconnect()、ctx.close()。
 
3.几个特殊的ChannelHandler
(1)ChannelInboundHandlerAdapter
(2)ChannelOutboundHandlerAdapter
(3)ByteToMessageDecoder
(4)SimpleChannelInboundHandler
(5)MessageToByteEncoder
 
(1)ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter主要用于实现ChannelInboundHandler接口的所有方法,这样我们在继承它编写自己的ChannelHandler时就不需要实现ChannelHandler里的每种方法了,从而避免了直接实现ChannelHandler时需要实现其所有方法而导致代码显得冗余和臃肿。
[code]//Handles an I/O event or intercepts an I/O operation, and forwards it to its next handler in its ChannelPipeline.public interface ChannelHandler {    //Gets called after the ChannelHandler was added to the actual context and it's ready to handle events.    void handlerAdded(ChannelHandlerContext ctx) throws Exception;    //Gets called after the ChannelHandler was removed from the actual context and it doesn't handle events anymore.    void handlerRemoved(ChannelHandlerContext ctx) throws Exception;    //Gets called if a Throwable was thrown.    @Deprecated    void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;    //Indicates that the same instance of the annotated ChannelHandler can be added to one or more ChannelPipelines multiple times without a race condition.    @Inherited    @Documented    @Target(ElementType.TYPE)    @Retention(RetentionPolicy.RUNTIME)    @interface Sharable {        // no value    }}//Skeleton implementation of a ChannelHandler.public abstract class ChannelHandlerAdapter implements ChannelHandler {    // Not using volatile because it's used only for a sanity check.    boolean added;    //Return true if the implementation is Sharable and so can be added to different ChannelPipelines.    public boolean isSharable() {        Class clazz = getClass();        Map
您需要登录后才可以回帖 登录 | 立即注册