Netty源码解析(九) —— channel的write操作

io.netty.channel.AbstractChannel#write(java.lang.Object)

    @Override
    /**
     * channel的写操作
     */
    public ChannelFuture write(Object msg) {
        //调用pipline的write操作
        return pipeline.write(msg);
    }

调用pipline进行事件的传递

    @Override
    public final ChannelFuture write(Object msg) {
        return tail.write(msg);
    }

在pipline中调用TailContext节点的write方法
io.netty.channel.AbstractChannelHandlerContext#write(java.lang.Object,io.netty.channel.ChannelPromise)

    @Override
    public ChannelFuture write(final Object msg, final ChannelPromise promise) {
        //消息为空抛出异常
        if (msg == null) {
            throw new NullPointerException("msg");
        }

        try {
            //判断promise是否合法
            if (isNotValidPromise(promise, true)) {
                //如果不合法释放资源
                ReferenceCountUtil.release(msg);
                // cancelled
                return promise;
            }
        } catch (RuntimeException e) {
            //发生异常也释放
            ReferenceCountUtil.release(msg);
            throw e;
        }
        //写入消息到内存队列
        write(msg, false, promise);

        return promise;
    }
  1. 判断要写的消息是否为空
  2. 判断promise是否合法
  3. 写入消息到内存队列

io.netty.channel.AbstractChannelHandlerContext#write(java.lang.Object,boolean,io.netty.channel.ChannelPromise)

   /**
     * @param msg bytebuf消息对象
     * @param flush 是否需要flush
     * @param promise
     */
    private void write(Object msg, boolean flush, ChannelPromise promise) {
        //获取下一个outbound节点
        AbstractChannelHandlerContext next = findContextOutbound();
        final Object m = pipeline.touch(msg, next);
        EventExecutor executor = next.executor();
        //在 EventLoop 的线程中
        if (executor.inEventLoop()) {
            if (flush) {
                next.invokeWriteAndFlush(m, promise);
            } else {
                //调用tailContext上一个节点  invokeWrite
                next.invokeWrite(m, promise);
            }
        } else {
            AbstractWriteTask task;
            if (flush) {
                task = WriteAndFlushTask.newInstance(next, m, promise);
            }  else {
                //创建write任务
                task = WriteTask.newInstance(next, m, promise);
            }
            //提交任务到eventLoop任务队列
            safeExecute(executor, task, promise, m);
        }
    }

获取下一个outbound节点,调用invokeWrite方法,走用户自定义的outBound handler节点,最终到达HeadContext节点的write方法
io.netty.channel.DefaultChannelPipeline.HeadContext#write

        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
            unsafe.write(msg, promise);
        }

调用unsafe 的io.netty.channel.AbstractChannel.AbstractUnsafe#write

        @Override
        public final void write(Object msg, ChannelPromise promise) {
            assertEventLoop();

            ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
            //内存队列为空
            if (outboundBuffer == null) {
                // If the outboundBuffer is null we know the channel was closed and so
                // need to fail the future right away. If it is not null the handling of the rest
                // will be done in flush0()
                // See https://github.com/netty/netty/issues/2362
                safeSetFailure(promise, WRITE_CLOSED_CHANNEL_EXCEPTION);
                // release message now to prevent resource-leak
                //释放相关的资源
                ReferenceCountUtil.release(msg);
                return;
            }

            int size;
            try {
                //过滤写入的消息
                msg = filterOutboundMessage(msg);
                //计算消息的长度
                size = pipeline.estimatorHandle().size(msg);
                if (size < 0) {
                    size = 0;
                }
            } catch (Throwable t) {
                safeSetFailure(promise, t);
                //出现异常  释放资源
                ReferenceCountUtil.release(msg);
                return;
            }
            //添加消息到内存队列
            outboundBuffer.addMessage(msg, size, promise);
        }
  1. 判断内存队列是否为空
  2. 过滤写入的消息
  3. 计算消息的长度
  4. 添加消息到内存队列

io.netty.channel.nio.AbstractNioByteChannel#filterOutboundMessage

    /**
     * 过滤消息
     */
    protected final Object filterOutboundMessage(Object msg) {
        //属于ByteBuf
        if (msg instanceof ByteBuf) {
            ByteBuf buf = (ByteBuf) msg;
            //如果是直接内存  返回msg
            if (buf.isDirect()) {
                return msg;
            }
            //不是直接内存  进行封装再返回
            return newDirectBuffer(buf);
        }

        if (msg instanceof FileRegion) {
            return msg;
        }

        throw new UnsupportedOperationException(
                "unsupported message type: " + StringUtil.simpleClassName(msg) + EXPECTED_TYPES);
    }

io.netty.channel.ChannelOutboundBuffer#addMessage

    public void addMessage(Object msg, int size, ChannelPromise promise) {
        //包装msg创建一个entry
        Entry entry = Entry.newInstance(msg, size, total(msg), promise);
        if (tailEntry == null) {
            flushedEntry = null;
        } else {
            //把这个节点添加到内存队列的尾部
            Entry tail = tailEntry;
            tail.next = entry;
        }
        tailEntry = entry;
        if (unflushedEntry == null) {
            unflushedEntry = entry;
        }

        // increment pending bytes after adding message to the unflushed arrays.
        // See https://github.com/netty/netty/issues/1619
        incrementPendingOutboundBytes(entry.pendingSize, false);
    }

猜你喜欢

转载自blog.csdn.net/u011702633/article/details/82116283