NOTE

2. Initialize Channel

1. Code to analyze 2. Obtain the channel pipeline and add a ChannelInitializer

JavaCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Code to Analyze

init(channel);

2. Obtain the Channel Pipeline and Add a ChannelInitializer

void init(Channel channel) throws Exception {
    // Set options.
    final Map<ChannelOption<?>, Object> options = options0();
    synchronized (options) {
        setChannelOptions(channel, options, logger);
    }
    // Set attrs.
    final Map<AttributeKey<?>, Object> attrs = attrs0();
    synchronized (attrs) {
        for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
            @SuppressWarnings("unchecked")
            AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
            channel.attr(key).set(e.getValue());
        }
    }

    // Obtain the pipeline associated with the channel.
    ChannelPipeline p = channel.pipeline();

    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()));
    }

    // Add ChannelInitializer to the pipeline.
    p.addLast(new ChannelInitializer<Channel>() {
        // At a later stage, "2. actual registration" calls back this initChannel method.
        @Override
        public void initChannel(final Channel ch) throws Exception {
            final ChannelPipeline pipeline = ch.pipeline();
            // 1. Add our own ChannelHandler to the pipeline.
            ChannelHandler handler = config.handler();
            if (handler != null) {
                pipeline.addLast(handler);
            }

            ch.eventLoop().execute(new Runnable() {
                @Override
                // 2. Add ServerBootstrapAcceptor to the pipeline.
                public void run() {
                    pipeline.addLast(new ServerBootstrapAcceptor(
                            ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                }
            });
        }
    });
}

The key point in the code above is that it obtains the pipeline corresponding to the current channel and adds a ChannelInitializer.

Inside this ChannelInitializer, the handler we configured in ServerBootstrap is added to the pipeline, and finally a ServerBootstrapAcceptor is added.

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub