io-5-netty-工作原理

来源:互联网 发布:软件招商加盟政策 编辑:程序博客网 时间:2024/06/10 21:47

ServerBootStrap

    服务启动辅助类,无参构造,采用builder模式(返回本对象构造参数)。

group (初始化线程组)

//加入线程组  public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {        super.group(parentGroup);  //线程parentGroup 加入父对象中        if (childGroup == null) {            throw new NullPointerException("childGroup");        }        if (this.childGroup != null) {            throw new IllegalStateException("childGroup set already");        }        this.childGroup = childGroup;  //指定子子线程组          return this;      }//父类 AbstractBootstrap 方法 public B group(EventLoopGroup group) {        if (group == null) {            throw new NullPointerException("group");        }        if (this.group != null) {            throw new IllegalStateException("group set already");        }        this.group = group;   //初始化父线程组 parent        return (B) this;    }

channel(创建指定channel)

//初始化工厂获取channel public B channel(Class<? extends C> channelClass) {        if (channelClass == null) {            throw new NullPointerException("channelClass");        }        return channelFactory(new ReflectiveChannelFactory<C>(channelClass));  //由工程创建    }//初始化工厂  public B channelFactory(ChannelFactory<? extends C> channelFactory) {        if (channelFactory == null) {            throw new NullPointerException("channelFactory");        }        if (this.channelFactory != null) {            throw new IllegalStateException("channelFactory set already");        }        this.channelFactory = channelFactory;        return (B) this;    }    //ReflectiveChannelFactory 工厂获取channel方法    public T newChannel() {        try {            return clazz.newInstance();   //jdk反射获取        } catch (Throwable t) {            throw new ChannelException("Unable to create Channel from class " + clazz, t);        }    }

option(设置参数)

//可选参数设置 public <T> B option(ChannelOption<T> option, T value) {        if (option == null) {            throw new NullPointerException("option");        }        //设置的参数值为null 则移除        if (value == null) {            synchronized (options) {                options.remove(option);            }        } else {            //保存到参数集合            synchronized (options) {                options.put(option, value);            }        }        return (B) this;    }

childHandler(配置io处理事件)

//初始化io处理事件 /**     * Set the {@link ChannelHandler} which is used to serve the request for the {@link Channel}'s.     */public ServerBootstrap childHandler(ChannelHandler childHandler) {        if (childHandler == null) {            throw new NullPointerException("childHandler");        }        this.childHandler = childHandler;        return this;    }

bind(开启服务类)

//绑定端口 public ChannelFuture bind(SocketAddress localAddress) {        validate();   //参数校验 是否先实现初始化        if (localAddress == null) {            throw new NullPointerException("localAddress");        }        return doBind(localAddress);    }// 真正的开启服务 private ChannelFuture doBind(final SocketAddress localAddress) {        final ChannelFuture regFuture = initAndRegister();        final Channel channel = regFuture.channel();        if (regFuture.cause() != null) {            return regFuture;        }        if (regFuture.isDone()) {            // At this point we know that the registration was complete and successful.            ChannelPromise promise = channel.newPromise();            doBind0(regFuture, channel, localAddress, promise);            return promise;        } else {            // Registration future is almost always fulfilled already, but just in case it's not.            final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);            regFuture.addListener(new ChannelFutureListener() {                @Override                public void operationComplete(ChannelFuture future) throws Exception {                    Throwable cause = future.cause();                    if (cause != null) {                        // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an                        // IllegalStateException once we try to access the EventLoop of the Channel.                        promise.setFailure(cause);                    } else {                        // Registration was successful, so set the correct executor to use.                        // See https://github.com/netty/netty/issues/2586                        promise.executor = channel.eventLoop();                    }                    doBind0(regFuture, channel, localAddress, promise);                }            });            return promise;        }
initAndRegister
// final ChannelFuture initAndRegister() {        final Channel channel = channelFactory().newChannel();  // 由前面初始化的channel反射工厂获取channel(NioServerSocketChannel)        try {            init(channel);        } catch (Throwable t) {            channel.unsafe().closeForcibly();            // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor            return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);        }        ChannelFuture regFuture = group().register(channel);        if (regFuture.cause() != null) {            if (channel.isRegistered()) {                channel.close();            } else {                channel.unsafe().closeForcibly();            }        }        return regFuture;    }
init
  @Override    void init(Channel channel) throws Exception {        final Map<ChannelOption<?>, Object> options = options();  //获取前面添加的可选参数集合        synchronized (options) {            channel.config().setOptions(options);  //设置对应参数        }        //同options        final Map<AttributeKey<?>, Object> attrs = attrs();        synchronized (attrs) {            for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {                @SuppressWarnings("unchecked")                AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();                channel.attr(key).set(e.getValue());            }        }        //将AbstractBootstrap 注册handler 添加到NioServerSocketChannel中        ChannelPipeline p = channel.pipeline();  // NioServerSocketChannel创建时 AbstractBootstrap 中DefaultChannelPipeline        if (handler() != null) {            p.addLast(handler());        }        //TODO         final EventLoopGroup currentChildGroup = childGroup;        final ChannelHandler currentChildHandler = childHandler;        final Entry<ChannelOption<?>, Object>[] currentChildOptions;        final Entry<AttributeKey<?>, Object>[] currentChildAttrs;        synchronized (childOptions) {            currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));        }        synchronized (childAttrs) {            currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));        }        //添加用于服务启动的io事件ServerBootstrapAcceptor        p.addLast(new ChannelInitializer<Channel>() {            @Override            public void initChannel(Channel ch) throws Exception {                ch.pipeline().addLast(new ServerBootstrapAcceptor(                        currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));            }        });    }

register

// eventLoop 为parentLoop 即 boss public final void register(EventLoop eventLoop, final ChannelPromise promise) {            if (eventLoop == null) {                throw new NullPointerException("eventLoop");            }            if (promise == null) {                throw new NullPointerException("promise");            }            if (isRegistered()) {                promise.setFailure(new IllegalStateException("registered to an event loop already"));                return;            }            if (!isCompatible(eventLoop)) {                promise.setFailure(                        new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));                return;            }            // It's necessary to reuse the wrapped eventloop object. Otherwise the user will end up with multiple            // objects that do not share a common state.            if (AbstractChannel.this.eventLoop == null) {                AbstractChannel.this.eventLoop = new PausableChannelEventLoop(eventLoop);            } else {                AbstractChannel.this.eventLoop.unwrapped = eventLoop;            }            // 判断是否为 eventloop 线程模式            //将NioServerSocketChannel 注册 Selector(eventLoop)            if (eventLoop.inEventLoop()) {                register0(promise);              } else {                try {                //用任务队列形式                    eventLoop.execute(new OneTimeTask() {                        @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);                }            }        }
    服务端启动成功,执行NioEventLoop run 方法。      1.轮训selectedKeys      2.接受请求客户端      3. pipeline.fireChannelRead由head.read - 》 ServerBootStrap channelRead - 》 将socktChannel 事件加入到pipeline,并加入注册监听就绪位。