zoukankan      html  css  js  c++  java
  • netty源码分析一

    一个channel对应一个pipeline,pipeline是channel的成员变量,初始化channel的时候就初始化了pipeline,一个pipeline里面包含多个handler,其中在初始化handler的时候,会同时初始化head/tail两个handlerContext;一个DefaultChannelHandlerContext里面包含一个handler,换句话说handler是以handlerContext的形式存在。

    public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {
    
        private static final InternalLogger logger = InternalLoggerFactory.getInstance(AbstractChannel.class);
    
        private final Channel parent;  // 代表父类channel
        private final ChannelId id;    // 采用默认方式生成的全局唯一id
        //实现具体的连接与读/写数据,如网络的读/写、链路关闭、发起连接等
        private final Unsafe unsafe;   // Unsafe实例
        //一个Handler的容器,也可以将其理解为一个Handler链。Handler主要处理数据的编/解码和业务逻辑。
        private final DefaultChannelPipeline pipeline; // 当前channel对应的DefaultChannelPipeline
        private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
        private final CloseFuture closeFuture = new CloseFuture(this);
    
        private volatile SocketAddress localAddress;
        private volatile SocketAddress remoteAddress;
        private volatile EventLoop eventLoop;  // 当前channel注册的EventLoop 每个Channel对应一条EventLoop线程。
        private volatile boolean registered;
        private boolean closeInitiated;
        private Throwable initialCloseCause;
    
        /**
         * Cache for the string representation of this channel
         */
        private boolean strValActive;
        private String strVal;
    
        /**
         * Creates a new instance.
         *
         * @param parent the parent of this channel. {@code null} if there's no parent.
         */
        protected AbstractChannel(Channel parent) {
            this.parent = parent;
            id = newId();
            unsafe = newUnsafe();
            pipeline = newChannelPipeline(); // 创建pipeline
        }
    }
    

    下面是pipeline的具体实现类,可以看到在初始化pipeline的时候,也初始化了head/tail两个变量, 同时改变了指向

    public class DefaultChannelPipeline implements ChannelPipeline {
        
        // pipeline里面
        final AbstractChannelHandlerContext head;
        final AbstractChannelHandlerContext tail;
    
        private final Channel channel;
        private final ChannelFuture succeededFuture;
        private final VoidChannelPromise voidPromise;
        private final boolean touch = ResourceLeakDetector.isEnabled();
        private boolean registered;
    
        protected DefaultChannelPipeline(Channel channel) {
            this.channel = ObjectUtil.checkNotNull(channel, "channel");// 这个方法值得借鉴
            succeededFuture = new SucceededChannelFuture(channel, null);
            voidPromise =  new VoidChannelPromise(channel, true);
    
            // 创建两个节点
            tail = new TailContext(this); //AbstractChannelHandlerContext
            head = new HeadContext(this); //AbstractChannelHandlerContext的子类
    
            head.next = tail;
            tail.prev = head;
        }
    }
    

    pipeline里面保存着链表的头结点和尾节点,因为很容易向链表中添加元素,具体方法如下:

        // 这个方法向链表里面添加节点
        private void addLast0(AbstractChannelHandlerContext newCtx) {
            AbstractChannelHandlerContext prev = tail.prev;
            newCtx.prev = prev;
            newCtx.next = tail;
            prev.next = newCtx;
            tail.prev = newCtx;
        }
    

    在执行handler的过程中需要一个一个的遍历链表,具体方法如下:

     private AbstractChannelHandlerContext findContextInbound(int mask) {// 这个是从链表里面获取一个元素 那么是怎么添加进去的呢?这个方法见上面
            logger.info("findContextInbound-_-");
            AbstractChannelHandlerContext ctx = this;
            do {
                ctx = ctx.next;
            } while ((ctx.executionMask & mask) == 0);
            return ctx;
        }
    
  • 相关阅读:
    刚刚学习Silverlight
    给文本框添加水印效果
    .net 下实现下载
    UpdatePanel中弹出对话框
    用VS.NET开发在Linux Apache Tomcat上运行的应用
    玩儿条形码之条码生成
    关于ContextSwitchDeadlock
    第一个Grasshoper应用
    WebService实现Ajax
    使用decorator的线程同步
  • 原文地址:https://www.cnblogs.com/d9e84208/p/15485264.html
Copyright © 2011-2022 走看看