接上一节eventLoopGroup初始化过程,本节分析服务端启动的流程。
//配置服务端的NIO线程组 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel channel) throws Exception { channel.pipeline() .addLast(new GateServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 512) .option(ChannelOption.SO_KEEPALIVE, true); //绑定端口,同步等待成功 ChannelFuture f = bootstrap.bind(port).sync(); f.channel().closeFuture().sync(); }catch (Exception e){ e.printStackTrace(); }finally { try { bossGroup.shutdownGracefully().sync(); workGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { e.printStackTrace(); } }
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) { super.group(parentGroup); if (childGroup == null) { throw new NullPointerException("childGroup"); } else if (this.childGroup != null) { throw new IllegalStateException("childGroup set already"); } else { this.childGroup = childGroup; return this; } }
bossGroup赋值给父类AbstractBootstrap的group, workGroup赋值给ServerBootstrap的childGroup。
public B channel(Class extends C> channelClass) { if (channelClass == null) { throw new NullPointerException("channelClass"); } else { return this.channelFactory((io.netty.channel.ChannelFactory)(new ReflectiveChannelFactory(channelClass))); } }
ReflectiveChannelFactory封装了传入的NioServerSocketChannel.class,再赋值给AbstractBootstrap.channelFactory
public ServerBootstrap childHandler(ChannelHandler childHandler) { if (childHandler == null) { throw new NullPointerException("childHandler"); } else { this.childHandler = childHandler; return this; } }
SO_BACKLOG:TCP三次握手ack队列的大小。更具体的内容可以参考tcp backlog参数
public ChannelFuture bind(SocketAddress localAddress) { this.validate(); if (localAddress == null) { throw new NullPointerException("localAddress"); } else { return this.doBind(localAddress); } }
校验AbstractBootstrap的group和channelFactory是否为null,校验ServerBootstrap的childGroup和childHandler是否为null。重点分析下AbstractBootstrap.doBind过程
private ChannelFuture doBind(final SocketAddress localAddress) { final ChannelFuture regFuture = this.initAndRegister(); final Channel channel = regFuture.channel(); if (regFuture.cause() != null) { return regFuture; } else if (regFuture.isDone()) { ChannelPromise promise = channel.newPromise(); doBind0(regFuture, channel, localAddress, promise); return promise; } else { final AbstractBootstrap.PendingRegistrationPromise promise = new AbstractBootstrap.PendingRegistrationPromise(channel); regFuture.addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { Throwable cause = future.cause(); if (cause != null) { promise.setFailure(cause); } else { promise.registered(); AbstractBootstrap.doBind0(regFuture, channel, localAddress, promise); } } }); return promise; } }
final ChannelFuture initAndRegister() { Channel channel = null; try { channel = this.channelFactory.newChannel(); this.init(channel); } catch (Throwable var3) { if (channel != null) { channel.unsafe().closeForcibly(); return (new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE)).setFailure(var3); } return (new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE)).setFailure(var3); } ChannelFuture regFuture = this.config().group().register(channel); if (regFuture.cause() != null) { if (channel.isRegistered()) { channel.close(); } else { channel.unsafe().closeForcibly(); } } return regFuture; }this.newChannel方法在ReflectiveChannelFactory类中通过反射实例化NioServerSocketChannel。
public NioServerSocketChannel(java.nio.channels.ServerSocketChannel channel) { super((Channel)null, channel, 16); this.config = new NioServerSocketChannel.NioServerSocketChannelConfig(this, this.javaChannel().socket()); }
主要工作是把ServerBootstrapAcceptor放到了pipeline的链表中
p.addLast(new ChannelHandler[]{new ChannelInitializer() { public void initChannel(final Channel ch) throws Exception { final ChannelPipeline pipeline = ch.pipeline(); ChannelHandler handler = ServerBootstrap.this.config.handler(); if (handler != null) { pipeline.addLast(new ChannelHandler[]{handler}); } ch.eventLoop().execute(new Runnable() { public void run() { pipeline.addLast(new ChannelHandler[]{new ServerBootstrap.ServerBootstrapAcceptor(ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)}); } }); } }});
group方法返回的是bossGroup,bossGroup是MultithreadEventLoopGroup的子类
public ChannelFuture register(Channel channel) { return this.next().register(channel); }
跟进this.next方法,可以看到该方法是从chooser中拿出一个eventExecutor
public EventExecutor next() { return this.chooser.next(); }
register调用了SingleThreadEventLoop类的方法,首先将NioServerSocketChannel和当前线程封装成DefaultChannelPromise对象
public ChannelFuture register(Channel channel) { return this.register((ChannelPromise)(new DefaultChannelPromise(channel, this))); }
再调用unsafe的register方法,由前面可知,unsafe就是AbstractNioMessageChannel.NioMessageUnsafe对象
public ChannelFuture register(ChannelPromise promise) { ObjectUtil.checkNotNull(promise, "promise"); promise.channel().unsafe().register(this, promise); return promise; }
boolean firstRegistration = this.neverRegistered; AbstractChannel.this.doRegister(); this.neverRegistered = false; AbstractChannel.this.registered = true; AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded(); this.safeSetSuccess(promise); AbstractChannel.this.pipeline.fireChannelRegistered(); if (AbstractChannel.this.isActive()) { if (firstRegistration) { AbstractChannel.this.pipeline.fireChannelActive(); } else if (AbstractChannel.this.config().isAutoRead()) { this.beginRead(); } }
再回到AbstractBootstrap.doBind方法上,跟进doBind0 -> AbstractChannel.bind -> DefaultChannelPipeline.bind
public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) { return this.tail.bind(localAddress, promise); }
this.findContextOutbound方法从tail开始循环向前找到属性outbound为true的AbstractChannelHandlerContext,返回HeadContext,调用headContext的bind方法
final AbstractChannelHandlerContext next = this.findContextOutbound(); EventExecutor executor = next.executor(); if (executor.inEventLoop()) { next.invokeBind(localAddress, promise); }
跟进unsafe.bind方法
try { AbstractChannel.this.doBind(localAddress); } catch (Throwable var5) { this.safeSetFailure(promise, var5); this.closeIfClosed(); return; } if (!wasActive && AbstractChannel.this.isActive()) { this.invokeLater(new Runnable() { public void run() { AbstractChannel.this.pipeline.fireChannelActive(); } }); }
AbstractChannel.this.doBind(localAddress)调用java nio的ServerSocketChannelImpl绑定了地址和端口
protected void doBind(SocketAddress localAddress) throws Exception { if (PlatformDependent.javaVersion() >= 7) { this.javaChannel().bind(localAddress, this.config.getBacklog()); } else { this.javaChannel().socket().bind(localAddress, this.config.getBacklog()); } }
AbstractChannel.this.pipeline.fireChannelActive在pipeline链表上传播Active和Read事件
public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelActive(); this.readIfIsAutoRead(); }
服务端完成绑定,并且激活channel和等待客户端read事件