zoukankan      html  css  js  c++  java
  • ChannelPipeline

    概述

      对于一个请求,可能会需要很多的处理逻辑,如果把所有的处理逻辑都放在一个ChannelHandler中,那么代码会十分的臃肿,因此需要把逻辑放在不同的ChannelHandler中实现面向对象的单一职责原则。Netty使用责任链模式把负责不同逻辑的ChannelHandler组合在一起,ChannelPipeline就是ChannelHandler的容器,每一个新建的Channel,Netty都会自动为之分配一个新的ChannelPipeline,这种分配是自动的,且这种绑定在netty整个生命周期中是永久性的。ChannelPipeline会负责Channel所有事件的处理。

      ChannelPipeline会按照相反的顺序调用ChannelHandler处理入栈和出栈事件。

      

      

    源码  

    addBefor

      把名称为name的handler添加到baseName的前面,调用了一个重载的方法。

        @Override
        public final ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) {
            return addBefore(null, baseName, name, handler);
        }

      group传入的是null,不需要考虑。

    • 首先注意到整个代码用synchronized包裹起来,说明这是ChannelPipe是一个线程安全的对象,这是因为netty允许在运行时候动态修改ChannelPipe的内容,那么就存在修改线程和正常运行线程同时访问ChannelPipe的情况,需要使用synchronized来避免潜在的线程安全问题。
    • checkMultiplicity判断handler是否可以共享,如果handler已经添加且不可共享,抛出异常。
    • 对handler的名称进行检查(filterName),如果名称重复抛出异常,如果name为Null则生成一个name。
    • 调用getContextOrDie从容器中找到baseName的handler,如这个方法名字暗示,如果没有找到就抛出异常(OrDie)。
    • 新建ChannelHandlerContext作为新handler的上下文,并添加到Pipeline里,pipeline说白了就是个双向链表,添加的方法也很简单,ChannelPipeline持有双向链表的头节点和尾节点。
        @Override
        public final ChannelPipeline addBefore(
                EventExecutorGroup group, String baseName, String name, ChannelHandler handler) {
            final AbstractChannelHandlerContext newCtx;
            final AbstractChannelHandlerContext ctx;
            synchronized (this) {
                checkMultiplicity(handler);
                name = filterName(name, handler);
                ctx = getContextOrDie(baseName);
    
                newCtx = newContext(group, name, handler);
    
                addBefore0(ctx, newCtx);
    
                // If the registered is false it means that the channel was not registered on an eventloop yet.
                // In this case we add the context to the pipeline and add a task that will call
                // ChannelHandler.handlerAdded(...) once the channel is registered.
                if (!registered) {
                    newCtx.setAddPending();
                    callHandlerCallbackLater(newCtx, true);
                    return this;
                }
    
                EventExecutor executor = newCtx.executor();
                if (!executor.inEventLoop()) {
                    newCtx.setAddPending();
                    executor.execute(new Runnable() {
                        @Override
                        public void run() {
                            callHandlerAdded0(newCtx);
                        }
                    });
                    return this;
                }
            }
            callHandlerAdded0(newCtx);
            return this;
        }

     

  • 相关阅读:
    (六)面向对象进阶
    (五)绑定方法与非绑定方法
    (四)封装
    (三)多态与多态性
    (二)继承与派生
    (一)面向对象的程序设计
    网络协议
    三.计算机网络简介
    二.计算机的发展史及多道技术
    一.计算机基础知识
  • 原文地址:https://www.cnblogs.com/AshOfTime/p/10903044.html
Copyright © 2011-2022 走看看