首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

绑定端口并向Selector注册accept事件 2

绑定端口并向Selector注册accept事件 2

往下查看发现其实是从pipeline尾部开始绑定

    @Override
        public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
            //调用pipleline绑定
            return pipeline.bind(localAddress, promise);
        }
     
     @Override
        public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
            //从pipeline尾端开始绑定端口
            return tail.bind(localAddress, promise);
        }

那么tail其实是一个AbstractChannelHandlerContext的子类。主要干两件事,先往上找离自己最近的ChannelOutboundHandler,再去执行绑定端口

    @Override
        public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
            if (localAddress == null) {
                throw new NullPointerException("localAddress");
            }
            if (isNotValidPromise(promise, false)) {
                // cancelled
                return promise;
            }
            //从尾部往上找最近的一个`ChannelOutboundHandler`
            final AbstractChannelHandlerContext next = findContextOutbound();
            EventExecutor executor = next.executor();
            //对比当前线程与executor是否同一线程
            if (executor.inEventLoop()) {
                //执行绑定
                next.invokeBind(localAddress, promise);
            } else {
                safeExecute(executor, new Runnable() {
                    @Override
                    public void run() {
                        next.invokeBind(localAddress, promise);
                    }
                }, promise, null);
            }
            return promise;
        }

查看AbstractChannelHandlerContext#invokeBind()

    private void invokeBind(SocketAddress localAddress, ChannelPromise promise) {
            if (invokeHandler()) {
                try {
                    //进入具体的`ChannelOutboundHandler`调用绑定方法
                    ((ChannelOutboundHandler) handler()).bind(this, localAddress, promise);
                } catch (Throwable t) {
                    notifyOutboundHandlerException(t, promise);
                }
            } else {
                bind(localAddress, promise);
            }
        }

往下查看接口 ChannelOutboundHandler#bind()方法,这里每一个具体的实例其实实现的方式都是一样的,以ChannelOutboundHandlerAdapter为例
返回列表