美文网首页
Netty源码_ChannelPipeline和ChannelH

Netty源码_ChannelPipeline和ChannelH

作者: wo883721 | 来源:发表于2021-10-29 18:14 被阅读0次

    一. ChannelPipeline 接口

    1.1 介绍

    ChannelPipeline 相当于 ChannelHandler 的集合,用于处理或拦截Channel的入站事件和出站操作。

    • ChannelPipeline实现了拦截过滤器模式的高级形式,让用户完全控制事件的处理方式以及管道中的ChannelHandler如何相互交互。
    • 每个Channel都有自己独有的管道ChannelPipeline,在创建新通道时自动创建。

    这里就有两个问题:

    1. ChannelPipeline 是如何管理 ChannelHandler 集合?
    2. ChannelHandler 集合是如何处理I/O事件?

    1.1.1 管理ChannelHandler 集合

    ChannelPipeline 管理ChannelHandler 集合,是利用 ChannelHandler 创建一个上下文对象 ChannelHandlerContext, 而ChannelPipeline 存储的就是这个上下文对象。
    这个 ChannelHandlerContext 对象下一节将重点讲解。

    1.1.2 流程图

    ChannelPipeline 管理的 ChannelHandler 集合处理I/O事件的流程图如下:

    
                                                                                                     |
        +---------------------------------------------------+---------------+
        |                           ChannelPipeline         |               |
        |                                                  \|/              |
        |    +---------------------+            +-----------+----------+    |
        |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
        |    +----------+----------+            +-----------+----------+    |
        |              /|\                                  |               |
        |               |                                  \|/              |
        |    +----------+----------+            +-----------+----------+    |
        |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
        |    +----------+----------+            +-----------+----------+    |
        |              /|\                                  .               |
        |               .                                   .               |
        | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
        |        [ method call]                       [method call]         |
        |               .                                   .               |
        |               .                                  \|/              |
        |    +----------+----------+            +-----------+----------+    |
        |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
        |    +----------+----------+            +-----------+----------+    |
        |              /|\                                  |               |
        |               |                                  \|/              |
        |    +----------+----------+            +-----------+----------+    |
        |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
        |    +----------+----------+            +-----------+----------+    |
        |              /|\                                  |               |
        +---------------+-----------------------------------+---------------+
                        |                                  \|/
        +---------------+-----------------------------------+---------------+
        |               |                                   |               |
        |       [ Socket.read() ]                    [ Socket.write() ]     |
        |                                                                   |
        |  Netty Internal I/O Threads (Transport Implementation)            |
        +-------------------------------------------------------------------+
    

    可以看出 ChannelPipeline将管理的 ChannelHandler 分为两种:

    • ChannelInboundHandler 处理入站事件
      • 入站事件是被动接收事件,例如接收远端数据,通道注册成功,通道变的活跃等等。
      • 入站事件流向是从 ChannelPipeline 管理的 ChannelInboundHandler 列表头到尾。因为入站事件一般都是从远端发送过来,所以流向是从头到尾。
      • 采用拦截器的模式,由ChannelInboundHandler 决定是否处理列表中的下一个 ChannelInboundHandler
    • ChannelOutboundHandler 处理出站事件
      • 出站事件是主动触发事件,例如绑定,注册,连接,断开,写入等等。
      • 出站事件流向是从 ChannelPipeline 管理的 ChannelOutboundHandler 列表尾到头。因为出站事件最后要发送到远端,所以从尾到头。
      • 采用拦截器的模式,由ChannelInboundHandler 决定是否处理列表中的下一个 ChannelInboundHandler (因为是从尾到头,这里的下一个,在列表中其实是上一个)。

    1.2 源码

    public interface ChannelPipeline
            extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {
    
        /**
         * 在这个管道ChannelPipeline的开头插入给定的ChannelHandler。
         *
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified handler is {@code null}
         */
        ChannelPipeline addFirst(String name, ChannelHandler handler);
    
        /**
         * 在这个管道ChannelPipeline的开头插入给定的ChannelHandler。
         *
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified handler is {@code null}
         */
        ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
    
        /**
         * 在管道的最后追加给定的 ChannelHandler。
         *
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified handler is {@code null}
         */
        ChannelPipeline addLast(String name, ChannelHandler handler);
    
        /**
         * 在管道的最后追加给定的 ChannelHandler。
         *
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified handler is {@code null}
         */
        ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
    
        /**
         * 在此管道的现有ChannelHandler(名称是baseName)之前插入ChannelHandler。
         *
         * @throws NoSuchElementException
         *         if there's no such entry with the specified {@code baseName}
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified baseName or handler is {@code null}
         */
        ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
    
        /**
         * 在此管道的现有ChannelHandler(名称是baseName)之前插入ChannelHandler。
         *
         * @throws NoSuchElementException
         *         if there's no such entry with the specified {@code baseName}
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified baseName or handler is {@code null}
         */
        ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
    
        /**
         * 在此管道的现有ChannelHandler(名称是baseName)之后插入ChannelHandler。
         *
         * @throws NoSuchElementException
         *         if there's no such entry with the specified {@code baseName}
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified baseName or handler is {@code null}
         */
        ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
    
        /**
         * 在此管道的现有ChannelHandler(名称是baseName)之后插入ChannelHandler。
         *
         * @throws NoSuchElementException
         *         if there's no such entry with the specified {@code baseName}
         * @throws IllegalArgumentException
         *         if there's an entry with the same name already in the pipeline
         * @throws NullPointerException
         *         if the specified baseName or handler is {@code null}
         */
        ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
    
        /**
         * 在这个管道ChannelPipeline的开头插入多个 ChannelHandler。
         */
        ChannelPipeline addFirst(ChannelHandler... handlers);
    
        /**
         * 在这个管道ChannelPipeline的开头插入多个 ChannelHandler。
         */
        ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
    
        /**
         * 在管道的最后追加多个 ChannelHandler。
         */
        ChannelPipeline addLast(ChannelHandler... handlers);
    
        /**
         * 在管道的最后追加多个 ChannelHandler。
         */
        ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
    
        /**
         * 从管道中删除指定的 ChannelHandler
         *
         * @throws NoSuchElementException
         *         if there's no such handler in this pipeline
         * @throws NullPointerException
         *         if the specified handler is {@code null}
         */
        ChannelPipeline remove(ChannelHandler handler);
    
        /**
         * 从管道中删除指定名称的 ChannelHandler
         * 返回被删除的 ChannelHandler 对象
         * @throws NoSuchElementException
         *         if there's no such handler with the specified name in this pipeline
         * @throws NullPointerException
         *         if the specified name is {@code null}
         */
        ChannelHandler remove(String name);
    
        /**
         * 从管道中删除指定类型的 ChannelHandler
         * 返回被删除的 ChannelHandler 对象
         *
         * @throws NoSuchElementException
         *         if there's no such handler of the specified type in this pipeline
         * @throws NullPointerException
         *         if the specified handler type is {@code null}
         */
        <T extends ChannelHandler> T remove(Class<T> handlerType);
    
        /**
         * 删除管道中第一个的 ChannelHandler,并返回删除的 ChannelHandler 对象
         * @throws NoSuchElementException
         *         if this pipeline is empty
         */
        ChannelHandler removeFirst();
    
        /**
         * 删除管道中最后一个的 ChannelHandler,并返回删除的 ChannelHandler 对象
         * @throws NoSuchElementException
         *         if this pipeline is empty
         */
        ChannelHandler removeLast();
    
        /**
         * 用新的 newHandler 替换该管道中指定老的 oldHandler。
         *
         * @throws NoSuchElementException
         *         if the specified old handler does not exist in this pipeline
         * @throws IllegalArgumentException
         *         if a handler with the specified new name already exists in this
         *         pipeline, except for the handler to be replaced
         * @throws NullPointerException
         *         if the specified old handler or new handler is
         *         {@code null}
         */
        ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
    
        /**
         * 用新的 newHandler 替换该管道中指定名称老的 ChannelHandler。
         * 返回被替换老的 ChannelHandler
         *
         * @throws NoSuchElementException
         *         if the handler with the specified old name does not exist in this pipeline
         * @throws IllegalArgumentException
         *         if a handler with the specified new name already exists in this
         *         pipeline, except for the handler to be replaced
         * @throws NullPointerException
         *         if the specified old handler or new handler is
         *         {@code null}
         */
        ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
    
        /**
         * 用新的 newHandler 替换该管道中指定类型老的 ChannelHandler。
         * 返回被替换老的 ChannelHandler
         *
         * @throws NoSuchElementException
         *         if the handler of the specified old handler type does not exist
         *         in this pipeline
         * @throws IllegalArgumentException
         *         if a handler with the specified new name already exists in this
         *         pipeline, except for the handler to be replaced
         * @throws NullPointerException
         *         if the specified old handler or new handler is
         *         {@code null}
         */
        <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
                                             ChannelHandler newHandler);
    
        /**
         * 返回此管道中的第一个 ChannelHandler。
         * 如果管道为空,那么就返回 null
         */
        ChannelHandler first();
    
        /**
         * 返回此管道中第一个 ChannelHandler 的上下文对象 ChannelHandlerContext。
         * 如果管道为空,那么就返回 null
         */
        ChannelHandlerContext firstContext();
    
        /**
         * 返回此管道中的最后一个 ChannelHandler。
         * 如果管道为空,那么就返回 null
         */
        ChannelHandler last();
    
        /**
         * 返回此管道中最后一个 ChannelHandler 的上下文对象 ChannelHandlerContext。
         * 如果管道为空,那么就返回 null
         */
        ChannelHandlerContext lastContext();
    
        /**
         * 返回此管道中指定名称的 ChannelHandler。
         */
        ChannelHandler get(String name);
    
        /**
         * 返回此管道中指定类型的 ChannelHandler。
         */
        <T extends ChannelHandler> T get(Class<T> handlerType);
    
        /**
         * 返回此管道中指定ChannelHandler的上下文对象ChannelHandlerContext。
         */
        ChannelHandlerContext context(ChannelHandler handler);
    
        /**
         * 返回此管道中指定名称 ChannelHandler 的上下文对象ChannelHandlerContext。
         */
        ChannelHandlerContext context(String name);
    
        /**
         * 返回此管道中指定类型 ChannelHandler 的上下文对象ChannelHandlerContext。
         */
        ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
    
        /**
         * 返回此管道依附的通道 Channel。
         */
        Channel channel();
    
        /**
         * Returns the {@link List} of the handler names.
         * 返回此管道拥有的 ChannelHandler 名称的列表。
         */
        List<String> names();
    
        /**
         * 返回此管道拥有的 ChannelHandler 集合
         */
        Map<String, ChannelHandler> toMap();
    
        // -------   复写来自 ChannelInboundInvoker 中的方法  ---------//
        @Override
        ChannelPipeline fireChannelRegistered();
    
        @Override
        ChannelPipeline fireChannelUnregistered();
    
        @Override
        ChannelPipeline fireChannelActive();
    
        @Override
        ChannelPipeline fireChannelInactive();
    
        @Override
        ChannelPipeline fireExceptionCaught(Throwable cause);
    
        @Override
        ChannelPipeline fireUserEventTriggered(Object event);
    
        @Override
        ChannelPipeline fireChannelRead(Object msg);
    
        @Override
        ChannelPipeline fireChannelReadComplete();
    
        @Override
        ChannelPipeline fireChannelWritabilityChanged();
    
        @Override
        ChannelPipeline flush();
    }
    

    不要看 ChannelPipeline 方法很多,其实主要分为两类:

    1. 一类是管理 ChannelHandler 相关方法,比如向管道ChannelPipeline添加,删除,替换,查找 ChannelHandler 方法。
    2. 一类是继承自 ChannelInboundInvokerChannelOutboundInvoker 方法,用于发送入站和出站事件。

    1.2.1 管理 ChannelHandler

    1.2.1.1 添加

    添加到管道 ChannelPipelineChannelHandler都要有一个名字,可以根据这个名字在管道中查找到这个ChannelHandler

       ChannelPipeline addFirst(String name, ChannelHandler handler);
       ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
    
       ChannelPipeline addLast(String name, ChannelHandler handler);
       ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
        
       ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
       ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
      
       ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
       ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
    
       ChannelPipeline addFirst(ChannelHandler... handlers);
       ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
       
       ChannelPipeline addLast(ChannelHandler... handlers);
       ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
    
    • 可以向管道 ChannelPipeline 头或者尾插入一个或者多个ChannelHandler
    • 可以在管道ChannelPipeline中已存在的某个ChannelHandler(通过baseName 查找到) ,之前或者之后插入一个ChannelHandler

    你会发现每个添加方法都有多一个 EventExecutorGroup 参数的对应方法,它作用是什么呢?

    • 我们知道通道 Channel 是注册到一个事件轮询器 EventLoop 中,通道所有的IO 事件都是通过在这个事件轮询器中获取。
    • 那么默认情况下,通道 Channel 对应的管道 ChannelPipeline 所管理的 ChannelHandler 也都是在这个事件轮询器中处理的。
    • 这就要求 ChannelHandler不能有太耗时操作,尤其是不能有阻塞操作,这样会导致整个事件轮询器被阻塞,会影响注册到这个事件轮询器所有通道的IO 事件处理,以及这个事件轮询器包含的所有待执行任务和计划任务。
    • 但是我们真的有这个方面的需求怎么办呢? 因此 ChannelPipeline 提供了多一个 EventExecutorGroup 参数的方法,它会将添加的这个 ChannelHandler 的所有方法都放在指定的这个事件执行器组EventExecutorGroup中执行,这样就不会阻塞通道 Channel 对应的事件轮询器。

    1.2.1.2 删除

    ChannelPipeline remove(ChannelHandler handler);
    
    ChannelHandler remove(String name);
    
    <T extends ChannelHandler> T remove(Class<T> handlerType);
    
    ChannelHandler removeFirst();
    
    ChannelHandler removeLast();
    
    • 直接从管道中删除指定的 ChannelHandler 对象
    • 从管道删除指定名称name或者指定类型handlerTypeChannelHandler 对象,并返回它。
    • 删除管道头或者尾的ChannelHandler 对象,并返回它。

    1.2.1.3 替换

    ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
    
    ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
    
    <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,ChannelHandler newHandler);
    
    • 用新的 newHandler 替换该管道中指定老的 oldHandler
    • 用新的 newHandler 替换该管道中指定名称oldName或者指定类型oldHandlerType 对应的老 ChannelHandler, 并返回它。

    1.2.1.4 查找

    ChannelHandler get(String name);
    <T extends ChannelHandler> T get(Class<T> handlerType);
    
    ChannelHandlerContext context(ChannelHandler handler);
    ChannelHandlerContext context(String name);
    ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
    
    • 根据名字或者类型从管道中查找对应的 ChannelHandler 对象。
    • 根据 ChannelHandler 或者名字或者类型从管道中查找对应的 ChannelHandlerContext 对象。
    • 其实管道ChannelPipeline 存储的是ChannelHandlerContext 对象,它是由 ChannelHandler 对象创建的,可以通过ChannelHandlerContext直接获取ChannelHandler

    1.2.1.5 其他方法

    ChannelHandler first();
    ChannelHandlerContext firstContext();
    
    ChannelHandler last();
    ChannelHandlerContext lastContext();
    
    List<String> names();
    Map<String, ChannelHandler> toMap();
    
    • 获取管道头或者尾的 ChannelHandler 以及 ChannelHandlerContext 对象。
    • 获取管道拥有的 ChannelHandler 名称的列表。
    • 获取此管道拥有的 ChannelHandler 集合。

    1.2.2 继承自 ChannelInboundInvokerChannelOutboundInvoker 方法

    这两个接口与入站事件处理接口ChannelInboundHandler和出站事件处理接口ChannelOutboundHandler 息息相关。

    • ChannelInboundInvoker 是用来发送入站事件的;
    • ChannelOutboundInvoker 是用来发送出站事件的。

    ChannelPipeline 实现中:

    1. ChannelInboundInvoker 发送的入站事件,会直接通过管道管理的 ChannelInboundHandler 列表从头到尾的触发,采用拦截器模式,由 ChannelInboundHandler 决定是否继续调用下一个 ChannelInboundHandler 处理。
    2. ChannelOutboundInvoker 发送的出站事件,会直接通过管道管理的 ChannelOutboundHandler 列表从尾到头的触发,采用拦截器模式,由 ChannelOutboundHandler 决定是否继续调用下一个 ChannelOutboundHandler 处理。

    1.3 小结

    你会发现 ChannelPipeline 的主要功能就两个:

    1. 储存多个 ChannelHandler 的实例,将它们分为两类,入站事件处理器列表和出站事件处理器列表。
      • 其实 ChannelPipeline 里面储存的是由 ChannelHandler 创建的 ChannelHandlerContext 实例。
      • 储存的 ChannelHandler 列表是有顺序的,按照添加操作的顺序。
    2. IO 事件使用拦截器的模式通过 ChannelHandler 列表。
      • 对于入站事件是从头到尾地经过 ChannelInboundHandler 列表,由 ChannelInboundHandler 决定是否调用列表中下一个 ChannelInboundHandler
      • 对于出站事件是从尾到头地经过 ChannelOutboundHandler 列表,由 ChannelOutboundHandler 决定是否调用列表中上一个 ChannelOutboundHandler

    二. ChannelHandlerContext 接口

    2.1 介绍

    上下文ChannelHandlerContext接口与 ChannelPipeline 联系非常大

    其实它唯一创建的地方,就是当一个 ChannelHandler 添加到管道ChannelPipeline时,由ChannelPipeline创建一个包裹 ChannelHandler 的上下文ChannelHandlerContext对象添加进去。

    ChannelHandlerContext 接口的重要作用:

    1. ChannelHandlerContext 包裹这一个 ChannelHandler, ChannelHandlerContext 必属于一个管道 ChannelPipeline
      • 这些都是在 ChannelHandlerContext 创建的时候就绑定的。
      • 因为ChannelHandlerContext获取到对应的管道,因此动态修改它所属的ChannelPipeline
    2. ChannelHandlerContext 继承 ChannelInboundInvokerChannelOutboundInvoker
      • 表示ChannelHandlerContext 也可以发送 IO 事件,它可以通知所属的ChannelPipeline 最接近的处理程序器处理 IO 事件。
      • 对于入站事件,最接近的处理程序器就是当前 ChannelHandler 在管道中下一个入站处理器ChannelInboundHandler
      • 对于出站事件,最接近的处理程序器就是当前 ChannelHandler 在管道中上一个出站处理器ChannelOutboundHandler
      • 其实 ChannelPipeline 的拦截器功能,就是通过ChannelHandlerContext实现的,因为由ChannelHandlerContext决定是否要调用列表中的下一个处理器处理。
    3. 继承 AttributeMap 接口

      attr(AttributeKey) 方法允许您存储和访问与ChannelHandler,Channel及其上下文相关的有效信息。

    2.2 源码

    public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker {
    
        /**
         * 返回绑定到ChannelHandlerContext的通道Channel。
         */
        Channel channel();
    
        /**
         * 返回用于执行该上下文 ChannelHandlerContext 方法的执行器 EventExecutor,
         * 这个执行器 EventExecutor 可能和 通道Channel的EventExecutor一样,也有可能不一样。
         * 如果不一样,说明该上下文中方法的处理在另一个线程,不在通道Channel 的IO线程中处理,不会阻塞通道的IO线程。
         */
        EventExecutor executor();
    
        /**
         * ChannelHandlerContext的唯一名称。
         * 当将ChannelHandler添加到ChannelPipeline时使用该名称。
         * 可以使用此名称从ChannelPipeline 获取已注册的ChannelHandler。
         */
        String name();
    
        /**
         * 绑定此上下文的ChannelHandler对象。
         */
        ChannelHandler handler();
    
        /**
         * 如果属于此上下文的ChannelHandler已从ChannelPipeline中删除,则返回true。
         *
         * 注意这个方法只被EventLoop中的内部调用。
         */
        boolean isRemoved();
    
        @Override
        ChannelHandlerContext fireChannelRegistered();
    
        @Override
        ChannelHandlerContext fireChannelUnregistered();
    
        @Override
        ChannelHandlerContext fireChannelActive();
    
        @Override
        ChannelHandlerContext fireChannelInactive();
    
        @Override
        ChannelHandlerContext fireExceptionCaught(Throwable cause);
    
        @Override
        ChannelHandlerContext fireUserEventTriggered(Object evt);
    
        @Override
        ChannelHandlerContext fireChannelRead(Object msg);
    
        @Override
        ChannelHandlerContext fireChannelReadComplete();
    
        @Override
        ChannelHandlerContext fireChannelWritabilityChanged();
    
        @Override
        ChannelHandlerContext read();
    
        @Override
        ChannelHandlerContext flush();
    
        /**
         * 此上下文所属的管道`ChannelPipeline`。
         */
        ChannelPipeline pipeline();
    
        /**
         * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s.
         */
        ByteBufAllocator alloc();
    
        /**
         * @deprecated Use {@link Channel#attr(AttributeKey)}
         */
        @Deprecated
        @Override
        <T> Attribute<T> attr(AttributeKey<T> key);
    
        /**
         * @deprecated Use {@link Channel#hasAttr(AttributeKey)}
         */
        @Deprecated
        @Override
        <T> boolean hasAttr(AttributeKey<T> key);
    }
    

    ChannelHandlerContext 的功能大概分为两类:

    1. 继承自 ChannelInboundInvokerChannelOutboundInvoker

      ChannelInboundInvokerChannelOutboundInvoker 将在下一篇文章中介绍。

    2. 获取属性
      • ChannelHandler handler(): 绑定此上下文的事件处理器ChannelHandler
      • ChannelPipeline pipeline(): 此上下文所属的管道ChannelPipeline
      • EventExecutor executor(): 此上下文对应的事件处理器ChannelHandler 方法运行所在的线程,有可能是所属通道Channel 的事件轮询器,也有可能是用户额外的事件执行器。
      • String name(): 该上下文的名字,在所属管道中是唯一的。
      • boolean isRemoved(): 此上下文从管道中移除时,返回true
      • Channel channel(),ByteBufAllocator alloc(),attr(AttributeKey<T> key)hasAttr(AttributeKey<T> key);都是从管道得到对应的通道Channel,然后从通道中再获取相关属性。

    三. 总结

    1. ChannelPipeline 添加ChannelHandler时,会创建这个ChannelHandler 的上下文对象 ChannelHandlerContext,再添加到管道中。
    2. ChannelHandler 中可以得到这个上下文对象ChannelHandlerContext,这样它就可以:
      • 可以向上游或下游传递事件,实现责任链的功能,将事件传递给下一个处理器ChannelHandler 处理。
      • 可以动态修改管道ChannelPipeline,因为上下文对象可以获取所属的管道。因此它也可以从管道头或者尾重新处理事件。
      • 可以通过 attr(AttributeKey<T> key) 存储特定于该处理器ChannelHandler的信息。

    相关文章

      网友评论

          本文标题:Netty源码_ChannelPipeline和ChannelH

          本文链接:https://www.haomeiwen.com/subject/bfovaltx.html