3.2、AbstractChannel源码

类的字段
    private final Channel parent;    //父channel
    private final ChannelId id;      //唯一id
    private final Unsafe unsafe;     //实际处理I/O操作的类
    private final DefaultChannelPipeline pipeline;    //处理通道
    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;    //eventloop线程
    private volatile boolean registered;
 
类的构造方法
   protected AbstractChannel(Channel parent) {
        this.parent = parent;
        id = newId();
        unsafe = newUnsafe();
        pipeline = newChannelPipeline();
    }

    protected AbstractChannel(Channel parent, ChannelId id) {
        this.parent = parent;
        this.id = id;
        unsafe = newUnsafe();
        pipeline = newChannelPipeline();
    }
 
其中 newUnsafe()方法是抽象方法,由子类实现
protected abstract AbstractUnsafe newUnsafe();
 
每一个channel内部都有一个对应的Unsafe内部类。
 
而  newChannelPipeline()方法在这里就实现了
    protected DefaultChannelPipeline newChannelPipeline() {
        return new DefaultChannelPipeline(this);
    }
 
其中ChannelPipeline这里不做引申,用途:做为Handler的容器,为用户提供逻辑处理。AbstractChannel中对I/O事件的都由pipeline 来完成。
    public ChannelFuture bind(SocketAddress localAddress) {
        return pipeline.bind(localAddress);
    }
    public ChannelFuture connect(SocketAddress remoteAddress) {
        return pipeline.connect(remoteAddress);
    }
    public ChannelFuture disconnect() {
        return pipeline.disconnect();
    }
    public ChannelFuture close() {
        return pipeline.close();
    }
    public Channel flush() {
        pipeline.flush();
        return this;
    }
    public Channel read() {
        pipeline.read();
        return this;
    }
    public ChannelFuture write(Object msg) {
        return pipeline.write(msg);
    }
.....
 
pipeline只是一个Handler的容器,也可以理解为一个Handler链,具体的逻辑由Handler处理,而每个Handler都会分配一个EventLoop,最终的请求还是要EventLoop来执行,而EventLoop中又调用Channel中的内部类Unsafe对应的方法。
新建一个channel会自动创建一个ChannelPipeline。
    @Override
    public ChannelFuture register(final Channel channel, final ChannelPromise promise) {
        if (channel == null) {
            throw new NullPointerException("channel");
        }
        if (promise == null) {
            throw new NullPointerException("promise");
        }
        channel.unsafe().register(this, promise);//真正的执行者
        return promise;
    }
 
参考前面文章 "Channel简介" 中Unsafe接口的方法来看 I/O操作的具体实现。
 

register()方法:
将Channel中注册给EventLoop
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    if (eventLoop == null) {
        throw new NullPointerException("eventLoop");
    }
    if (isRegistered()) {//已经注册过了,则失败
        promise.setFailure(new IllegalStateException("registered to an event loop already"));
        return;
    }
    if (!isCompatible(eventLoop)) {//不兼容当前channel,子类实现
        promise.setFailure(
                new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
        return;
    }

    AbstractChannel.this.eventLoop = eventLoop;

    //每个EventLoop由固定的Thread执行
    //每个Cnel会分配一个EventLoop
    //一个EventLoop可以分配给多个Channnel
    if (eventLoop.inEventLoop()) {//见注释1
        register0(promise);
    } else {
        try {
            eventLoop.execute(new Runnable() {//放入eventloop的任务队列,这样做是为保证一个channel的所有处理都是走同一个线程
                @Override
                public void run() {
                    register0(promise);
                }
            });
        } catch (Throwable t) {
            logger.warn(
                    "Force-closing a channel whose registration task was not accepted by an event loop: {}",
                    AbstractChannel.this, t);
            closeForcibly();
            closeFuture.setClosed();
            safeSetFailure(promise, t);
        }
    }
}
 
注释1:
    /**
     * Calls {@link #inEventLoop(Thread)} with {@link Thread#currentThread()} as argument
     */
    boolean inEventLoop();

    /**
     * Return {@code true} if the given {@link Thread} is executed in the event loop,
     * {@code false} otherwise.
     */
    boolean inEventLoop(Thread thread);
 
如果给的线程是EventLoop线程池的线程,那就执行 register0()
 
register0()方法
private void register0(ChannelPromise promise) {
    try {
        if (!promise.setUncancellable() || !ensureOpen(promise)) {
            return;
        }
        boolean firstRegistration = neverRegistered;
        doRegister();//由子类实现,将当前Channel注册到EventLoop的多路复用器上
        neverRegistered = false;//从来没有注册过
        registered = true;//标记已经注册
        pipeline.invokeHandlerAddedIfNeeded();//加载Handler到pipeline
        safeSetSuccess(promise);//设置为成功
        pipeline.fireChannelRegistered();//触发channel的“注册”事件,将ChannelHandlerContext注册到pipeline
        if (isActive()) { //channel已经被激活
            if (firstRegistration) {//首次激活,则触发channel的“激活”事件
                pipeline.fireChannelActive();
            } else if (config().isAutoRead()) {//设置为AutoRead,则开始读取数据
                beginRead();//见下文
            }
        }
    } catch (Throwable t) {
        closeForcibly();
        closeFuture.setClosed();
        safeSetFailure(promise, t);
    }
}
 
beginRead()方法
public final void beginRead() {
    assertEventLoop();//assert !registered || eventLoop.inEventLoop(); channel没有注册或当前线程是eventLoop
    if (!isActive()) {
        return;
    }
    try {
        doBeginRead();//模板方法,子类实现
    } catch (final Exception e) {
        invokeLater(new Runnable() {
            @Override
            public void run() {
                pipeline.fireExceptionCaught(e);
            }
        });
        close(voidPromise());
    }
}
 


deregister()方法:
解除注册
@Override
public final void deregister(final ChannelPromise promise) {
    assertEventLoop();//assert !registered || eventLoop.inEventLoop();
    deregister(promise, false);
}
 
private void deregister(final ChannelPromise promise, final boolean fireChannelInactive) {
    if (!promise.setUncancellable()) {
        return;
    }

    if (!registered) {//已经解除注册
        safeSetSuccess(promise);
        return;
    }
    
    invokeLater(new Runnable() {//invokeLater()方法的具体含义可见下文 
        @Override
        public void run() {
            try {
                doDeregister();//模版方法,由子类实现,将Channel从EventLoop的多路复用器上删除
            } catch (Throwable t) {
                logger.warn("Unexpected exception occurred while deregistering a channel.", t);
            } finally {
                if (fireChannelInactive) {
                    pipeline.fireChannelInactive();//触发ChannelInavtive事件
                }
                if (registered) {
                    registered = false;
                    pipeline.fireChannelUnregistered();//触发ChannelUnregistered事件
                }
                safeSetSuccess(promise);
            }
        }
    });
}
 
 

bind()方法:
绑定channel到本地地址,然后触发激活事件
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
    assertEventLoop();

    if (!promise.setUncancellable() || !ensureOpen(promise)) {
        return;
    }
    if (Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST)) &&
        localAddress instanceof InetSocketAddress &&
        !((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress() &&
        !PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) {
        logger.warn(.......);
    }

    boolean wasActive = isActive();//绑定前的激活状态
    try {
        doBind(localAddress);//模板方法,由子类实现
    } catch (Throwable t) {
        safeSetFailure(promise, t);
        closeIfClosed();
        return;
    }

    if (!wasActive && isActive()) {//没有进行激活操作
        invokeLater(new Runnable() {//见下文
            @Override
            public void run() {
                pipeline.fireChannelActive();//触发“激活”事件
            }
        });
    }

    safeSetSuccess(promise);//设置成功
}
 
 
invokeLater()
其实就是想eventLoop提交一个任务
private void invokeLater(Runnable task) {
    try {
        eventLoop().execute(task);
    } catch (RejectedExecutionException e) {
        logger.warn("Can't invoke task later as EventLoop rejected it", e);
    }
}
 
 
 
 

connect()方法:
由子类 AbstractNioChannel 实现
 
 

disconnect()方法:
解除连接
public final void disconnect(final ChannelPromise promise) {
    assertEventLoop();
    if (!promise.setUncancellable()) {
        return;
    }
    boolean wasActive = isActive();//解除连接前的激活状态
    try {
        doDisconnect();//子类实现
    } catch (Throwable t) {
        safeSetFailure(promise, t);
        closeIfClosed();
        return;
    }
    if (wasActive && !isActive()) {//非激活状态
        invokeLater(new Runnable() {
            @Override
            public void run() {
                pipeline.fireChannelInactive();//触发ChannelInavtive事件
            }
        });
    }
    safeSetSuccess(promise);
    closeIfClosed(); // doDisconnect() 可能关闭Channel
}
 
 

write()方法:
将msg写到队列中等待flush
public final void write(Object msg, ChannelPromise promise) {
    assertEventLoop();

    ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
    if (outboundBuffer == null) {//表示Channel正在关闭,禁止写数据
        safeSetFailure(promise, WRITE_CLOSED_CHANNEL_EXCEPTION);
        ReferenceCountUtil.release(msg);//释放msg,防止泄漏
        return;
    }

    int size;
    try {
        msg = filterOutboundMessage(msg);//由子类AbstractNioByteChannel实现,过滤msg,如果不是ByteBuf或者FileRegion就抛错
        size = pipeline.estimatorHandle().size(msg);//计算msg的大小
        if (size < 0) {
            size = 0;
        }
    } catch (Throwable t) {
        safeSetFailure(promise, t);
        ReferenceCountUtil.release(msg);
        return;
    }

    outboundBuffer.addMessage(msg, size, promise);//添加到发送队列,等待flush
}
 
ChannelOutboundBuffer 的addMessage()
    public void addMessage(Object msg, int size, ChannelPromise promise) {
        Entry entry = Entry.newInstance(msg, size, total(msg), promise);
        if (tailEntry == null) {
            flushedEntry = null;
            tailEntry = entry;
        } else {
            Entry tail = tailEntry;
            tail.next = entry;
            tailEntry = entry;
        }
        if (unflushedEntry == null) {
            unflushedEntry = entry;
        }

        incrementPendingOutboundBytes(entry.pendingSize, false);
    }
 
 

flush()方法:
将队列中的msg冲刷到channel中
public final void flush() {
    assertEventLoop();

    ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
    if (outboundBuffer == null) {
        return;
    }

    outboundBuffer.addFlush();//添加一个标记,意味着所有以前添加的消息都被标记为刷新,并且能够处理它们。
    flush0();
}
 
flush0() 方法
protected void flush0() {
    if (inFlush0) {//已经冲刷
        return;
    }

    final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
    if (outboundBuffer == null || outboundBuffer.isEmpty()) {// Channel已经关闭或者已没有需要写的数据
        return;
    }

    inFlush0 = true;

    // Mark all pending write requests as failure if the channel is inactive.
    if (!isActive()) {//非激活
        try {
            if (isOpen()) {//channel还是打开的
                outboundBuffer.failFlushed(FLUSH0_NOT_YET_CONNECTED_EXCEPTION, true);//failFlushed()内部将队列的中的写请求标记为失败
            } else {
                outboundBuffer.failFlushed(FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
            }
        } finally {
            inFlush0 = false;
        }
        return;
    }

    try {
        doWrite(outboundBuffer);//由子类实现,将所有msg写入Channel
    } catch (Throwable t) {
        if (t instanceof IOException && config().isAutoClose()) {
            close(voidPromise(), t, FLUSH0_CLOSED_CHANNEL_EXCEPTION, false);
        } else {
            outboundBuffer.failFlushed(t, true);
        }
    } finally {
        inFlush0 = false;
    }
}
 


close()方法:
关闭Channel
public final void close(final ChannelPromise promise) {
    assertEventLoop();
    close(promise, CLOSE_CLOSED_CHANNEL_EXCEPTION, CLOSE_CLOSED_CHANNEL_EXCEPTION, false);
}

private void close(final ChannelPromise promise, final Throwable cause,
                   final ClosedChannelException closeCause, final boolean notify) {
    if (!promise.setUncancellable()) {
        return;
    }

    final ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
    if (outboundBuffer == null) {//Channel已经关闭
        if (!(promise instanceof VoidChannelPromise)) {
            closeFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    promise.setSuccess();// 当Channel关闭时,将此次close异步请求结果也设置为成功
                }
            });
        }
        return;
    }

    if (closeFuture.isDone()) {//已经成功关闭,保证底层close只执行一次
        safeSetSuccess(promise); 
        return; 
    }

    final boolean wasActive = isActive();
    this.outboundBuffer = null; // 这里可以做一个标识,前面关于 == null的判读的基础就是这里。
    
    //准备去关闭Channel。
    //如果返回一个Executor,调用者必须 将doClose0()包装成一个任务加入Executor。
    //如果返回null,必须执行 doClose0()
    Executor closeExecutor = prepareToClose();
    if (closeExecutor != null) {
        closeExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    doClose0(promise);
                } finally {
                    invokeLater(new Runnable() {//invokeLater见上文
                        @Override
                        public void run() {
                            outboundBuffer.failFlushed(cause, notify);
                            outboundBuffer.close(closeCause);
                            fireChannelInactiveAndDeregister(wasActive);
                        }
                    });
                }
            }
        });
    } else {
        try {
            doClose0(promise);
        } finally {
            outboundBuffer.failFlushed(cause, notify);
            outboundBuffer.close(closeCause);
        }
        if (inFlush0) {
            invokeLater(new Runnable() {
                @Override
                public void run() {
                    fireChannelInactiveAndDeregister(wasActive);//触发ChannelInavtive事件 和 触发ChannelUnregistered事件
                }
            });
        } else {
            fireChannelInactiveAndDeregister(wasActive);
        }
    }
}
 
doClose0() 方法
private void doClose0(ChannelPromise promise) {
    try {
        doClose();
        closeFuture.setClosed();
        safeSetSuccess(promise);
    } catch (Throwable t) {
        closeFuture.setClosed();
        safeSetFailure(promise, t);
    }
}
 
doClose() 方法
由子类 AbstractNioChannel 实现 
 


回顾上文:
  1. 每个Channel都有个一个Unsafe内部类,具体的逻辑都是Unsafe类实现
  2. 每个Channel都有一个EventLoop,EventLoop的Thread是固定的,所有的事件都是由同一条Thread执行,避免并发。
  3. 消息不是直接写到Channel中,而是先写入队列,然后在flush时一次写入Channel


 
 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

 
 
 
 





转载于:https://www.cnblogs.com/chenzl1024/p/7354648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值