Netty服务端Channel的创建与初始化

Netty创建服务端Channel时,从服务端 ServerBootstrap 类的 bind 方法进入,下图是创建服务端Channel的函数调用链。在后续代码中通过反射的方式创建服务端Channel,反射操作在创建服务端 Channel 对象的工厂的 newChannel 方法,创建服务端 Channel 对象的工厂在ServerBootstrap 类的 channel 方法中确定。
 
 
 
final ChannelFuture initAndRegister() {
    Channel channel = null;
    try {
        // 反射创建服务端Channel
        channel = channelFactory.newChannel();
        init(channel);              
    }
    ChannelFuture regFuture = config().group().register(channel);
       return regFuture;
}
反射创建服务端Channel的工厂:
public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {
 
    private final Class<? extends T> clazz;
 
    public ReflectiveChannelFactory(Class<? extends T> clazz) {
        this.clazz = clazz;
    }
 
    @Override
    public T newChannel() {
        return clazz.getConstructor().newInstance();
    }
}
在服务端创建Channel的过程中,上述代码中传入的Class类为 NioServerSocketChannel.class,这个类是在配置ServerBootstrap时通过其channel()方法确定的,所以创建的服务端Channel对象也就是 NioServerSocketChannel 类的对象,实例化 NioServerSocketChannel 类时会调用该类及其父类的一系列 构造方法,这一过程中将会创建 jdk 底层的 jdk channel 以及做一些基础的初始化工作,比如设置服务端Channel的阻塞模式,创建服务端Channel的id、unsafe、pipeline成员等。
 
 
创建 NioServerSocketChannel 类对象的具体流程:
 
public NioServerSocketChannel() {
    this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
 
public NioServerSocketChannel(SelectorProvider provider) {
    this(newSocket(provider));
}
 
public NioServerSocketChannel(ServerSocketChannel channel) {
    super(null, channel, SelectionKey.OP_ACCEPT);
    config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
 
protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
    super(parent, ch, readInterestOp);
}
 
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
    super(parent);
    this.ch = ch;
    this.readInterestOp = readInterestOp;
 
    ch.configureBlocking(false);
}
 
protected AbstractChannel(Channel parent) {
    this.parent = parent;
    id = newId();
    unsafe = newUnsafe();
    pipeline = newChannelPipeline();
}
由以上的构造方法可知,每一个Channel在创建的时候都会为其分配一个新的ChannelPipeline,这项关联是永久性的,Channel既不能附加另外一个ChannelPipeline,也不能分离其当前的。ChannelPipeline中以链式结构存储ChannelHandlerContext,在刚开始创建ChannelPipeline的时候会先创建两个节点:head、tail节点,后续再往ChannelPipeline中添加ChannelHandler时可调用ChannelPipeline的addLast方法进行添加,处理过程中会将ChannelHandler封装为ChannelHandlerContext,然后添加进去。
 
// 创建ChannelPipeline对象时会先创建head、tail节点
protected DefaultChannelPipeline(Channel channel) {
    this.channel = ObjectUtil.checkNotNull(channel, "channel");
    succeededFuture = new SucceededChannelFuture(channel, null);
    voidPromise =  new VoidChannelPromise(channel, true);
 
    tail = new TailContext(this);
    head = new HeadContext(this);
 
    head.next = tail;
    tail.prev = head;
}
 
// 在ChannelPipeline中新添加一个ChannelHandler
private void addLast0(AbstractChannelHandlerContext newCtx) {
    AbstractChannelHandlerContext prev = tail.prev;
    newCtx.prev = prev;
    newCtx.next = tail;
    prev.next = newCtx;
    tail.prev = newCtx;
}

 
服务端Channel创建完成后会对其进行初始化,初始化工作大概就是保存用户自定义的属性,然后配置服务端的pipeline,再通过保存的用户属性创建一个连接接入器,并将其添加到服务端的pipeline,连接接入器每次accept新的连接之后都会使用这些属性对新连接做一些配置,过程如下:
 
 
配置服务端的pipeline的过程如下:
ChannelPipeline p = channel.pipeline();
 
p.addLast(new ChannelInitializer<Channel>() {
    @Override
    public void initChannel(final Channel ch) throws Exception {
        final ChannelPipeline pipeline = ch.pipeline();
        // handler()方法返回由 ServerBootstrap 类的handler 方法设置的handler
        ChannelHandler handler = config.handler();
        if (handler != null) {
            pipeline.addLast(handler);
        }
 
        ch.eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                // ServerBootstrapAcceptor这个配置在服务端Pipeline中的handler,会对新接入的客户端Channel做一些配置,比如配置客户端                                       的ChannelPipeline
                pipeline.addLast(new ServerBootstrapAcceptor(
                        ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
            }
        });
    }
});
 
// ServerBootstrapAcceptor配置客户端Channel的过程
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    final Channel child = (Channel) msg;
 
    child.pipeline().addLast(childHandler);
 
    setChannelOptions(child, childOptions, logger);
 
    for (Entry<AttributeKey<?>, Object> e: childAttrs) {
        child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
    }
 
    childGroup.register(child).addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                forceClose(child, future.cause());
            }
        }
    });
}
 
至此Netty服务端Channel创建完成,并且完成了其初始化。
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/zviolet/p/12045331.html