美文网首页
ClientBootstrap简介

ClientBootstrap简介

作者: 追梦小蜗牛 | 来源:发表于2020-02-28 16:57 被阅读0次
photo-of-woman-reading-book-3747468.jpg

前言:

一直在零零碎碎的看关于netty的源码和《netty实战》,也一直想记录下自己的学习过程,但是由于种种原因,一直没写。万事开头难,一旦开个头,剩下的就只剩坚持了。不要等着什么都准备好,才去下笔,不要有太多的虚荣心,要更实事求是一点。只要自己稍微有点想法,就可以记录下来,刚开始可能写的不完善,不深入,但是日积月累,量变引起质变,所有的事情都有个发展过程,要遵循客观的自然规律。

简介:

相当于一个工具类,用来创建客户端Channel和发起连接请求。还可以配置一些channel的属性,channel其实就是对底层socket的抽象封装,简化、统一了一些操作。

API:

public class ClientBootstrap extends Bootstrap {

    public ClientBootstrap() {//构造一个不指定ChannelFactory的Bootstrap,在后续代码里set
        super();
    }

    public ClientBootstrap(ChannelFactory channelFactory) {//构造一个指定ChannelFactory的Bootstrap
        super(channelFactory);
    }

    public ChannelFuture connect() {
        SocketAddress remoteAddress = (SocketAddress) getOption("remoteAddress");
        if (remoteAddress == null) {
            throw new IllegalStateException("remoteAddress option is not set.");
        }
        return connect(remoteAddress);
    }

    public ChannelFuture connect(SocketAddress remoteAddress) {
        if (remoteAddress == null) {
            throw new NullPointerException("remotedAddress");
        }
        SocketAddress localAddress = (SocketAddress) getOption("localAddress");
        return connect(remoteAddress, localAddress);
    }

    public ChannelFuture connect(final SocketAddress remoteAddress, final SocketAddress localAddress) {

        if (remoteAddress == null) {
            throw new NullPointerException("remoteAddress");
        }

        final BlockingQueue<ChannelFuture> futureQueue =
            new LinkedBlockingQueue<ChannelFuture>();//保存channel连接remoteAddress的异步结果

        ChannelPipeline pipeline;
        try {
            pipeline = getPipelineFactory().getPipeline();
        } catch (Exception e) {
            throw new ChannelPipelineException("Failed to initialize a pipeline.", e);
        }

        pipeline.addFirst(
                "connector", new Connector(
                        this, remoteAddress, localAddress, futureQueue));//向pipeline里面添加一个handler

        getFactory().newChannel(pipeline);//@1:new channel() 这个方法里面做的事情还是不少的,下面会继续跟踪一下的。

        // Wait until the future is available.
        ChannelFuture future = null;
        do {
            try {
                future = futureQueue.poll(Integer.MAX_VALUE, TimeUnit.SECONDS);//从队列取出可用的ChannelFuture,如果没有可用的,会暂时阻塞住
            } catch (InterruptedException e) {
                // Ignore
            }
        } while (future == null);

        pipeline.remove("connector");//程序结束,从pipeline里面移除handler

        return future;
    }

    @ChannelPipelineCoverage("one")//表示是否线程安全
    static final class Connector extends SimpleChannelUpstreamHandler {
        private final Bootstrap bootstrap;
        private final SocketAddress localAddress;
        private final BlockingQueue<ChannelFuture> futureQueue;
        private final SocketAddress remoteAddress;
        private volatile boolean finished = false;

        Connector(
                Bootstrap bootstrap,
                SocketAddress remoteAddress,
                SocketAddress localAddress,
                BlockingQueue<ChannelFuture> futureQueue) {
            this.bootstrap = bootstrap;
            this.localAddress = localAddress;
            this.futureQueue = futureQueue;
            this.remoteAddress = remoteAddress;
        }

        @Override
        public void channelOpen(
                ChannelHandlerContext context,
                ChannelStateEvent event) {

            try {
                // Apply options.
                event.getChannel().getConfig().setOptions(bootstrap.getOptions());
            } finally {
                context.sendUpstream(event);
            }

            // Bind or connect.
            if (localAddress != null) {
                event.getChannel().bind(localAddress);
            } else {
                finished = futureQueue.offer(event.getChannel().connect(remoteAddress));
                assert finished;
            }
        }

        @Override
        public void channelBound(
                ChannelHandlerContext context,
                ChannelStateEvent event) {
            context.sendUpstream(event);

            // Connect if not connected yet.
            if (localAddress != null) {
                finished = futureQueue.offer(event.getChannel().connect(remoteAddress));
                assert finished;
            }
        }

        @Override
        public void exceptionCaught(
                ChannelHandlerContext ctx, ExceptionEvent e)
                throws Exception {
            ctx.sendUpstream(e);

            Throwable cause = e.getCause();
            if (!(cause instanceof NotYetConnectedException) && !finished) {
                e.getChannel().close();
                finished = futureQueue.offer(failedFuture(e.getChannel(), cause));
                assert finished;
            }
        }
    }
}

分析:

@1处的newChannel()方法的目的是构造一个客户端的channel,也就是NioClientSocketChannel,在NioClientSocketChannel的构造方法里面有一句代码:fireChannelOpen(this);这个方法用来触发ChannelPipeLine中的第一个handler,其实也就是继承于SimpleChannelUpstreamHandler的Connector类,也算是一个handler,用来开启HandlerPipeLine上的handler流水线。紧接着是sendUpstream()这个方法,最终会调用SimpleChannelHandler的handleUpstream()方法,这个方法主要负责把对应流的事件向下传递给子事件、并且调用适当的handler来继续处理......后续还会触发Connect事件......感觉逻辑挺多的,暂停一下,一口吃不了一个胖子。

总结:

netty的源码还是需要尽快投入精力和时间去好好研究一下,不然没有质的提升呀,加油呀,还有好多源码等着看呢......。

相关文章

  • ClientBootstrap简介

    前言: 一直在零零碎碎的看关于netty的源码和《netty实战》,也一直想记录下自己的学习过程,但是由于种种原因...

  • 18旅游二班各组自我简介汇总

    一组简介 二组简介 三组简介 四组简介 五组简介 六组简介 七组简介 八组简介

  • 简介

    上辈子,洛幽喜欢了东凡一辈子,没有结果,之后她死了,她不后悔,只是为什么她一睁眼,嗯?捏了捏自己的脸,她这是回到了...

  • 简介

    1.主动地去阅读。 2.阅读目的:获得资讯,获得理解 前者为了增进资讯,获得信息,不能增加理解力。后者为了理解更多...

  • 简介

    姓名:赵金星 电话:13903984903 坐标:河南三门峡市陕州区。 三个标签的自我介绍: 1.时间管理践行者 ...

  • 简介

    朱凝不过打错个字,便被天打雷劈回古代。 为毛别人穿个废柴嫡女,她穿个废柴庶女?地位更低了哎 哇喔,别人嫁王爷,她嫁...

  • 简介

    凌波网络考试系统,是一套运行于Windows系统之上的无纸化网络考试软件。包括试卷编辑、分发试卷、学生答卷、自动阅...

  • 简介

    名字:笨小孩 不是富二代的笨小孩为了生活选择了编程。在大多数人眼里可能感觉编程是很无聊很辛苦经常加班的事情,其实人...

  • 简介

    A Native Client web application consists of JavaScript, H...

  • 简介

    选择django作为毕设项目,和日后工作内容。故在简单得做了一个blog和毕设系统之间,想深入了解django,会...

网友评论

      本文标题:ClientBootstrap简介

      本文链接:https://www.haomeiwen.com/subject/fwedqhtx.html