2.Netty服务器的启动

383 阅读2分钟

windows环境下进入方法CTRL+🖱左键 回到上层方法CTRL+ALT+⬅

启动流程

  • 创建服务端Channel
  • 初始化服务端Channel
  • 注册selector
  • 端口绑定

创建服务端Channel

  • 代码入口 ->bind()
  • 注册并初始化 ->initAndRegister()
  • 创建服务端channel ->newChannel()

image.png image.png image.png image.png image.png image.png image.png

此处通过反射创建channel,而传入的class就是NioServerSocketChannel.class image.png

通过反射创建服务端Channel

  • 通过jdk创建底层jdk channel ->newSocket()
  • TCP参数配置类 ->new NioServerSocketChannelConfig()
  • AbstractNioChannel中设置非阻塞configureBlocking、创建id、unsafe、pipeline

image.png

newSocket再深入就会看到导入的包为import java.nio.channels.*; image.png 设置tcp参数类 image.png image.png image.png 设置非阻塞 image.png image.png 设置id、unsafe、pipeline image.png

初始化服务端channel

在上文newChannel()中通过反射创建channel之后,我们紧跟下一步

  • 代码入口 ->init()
  • set ChannelOptions和ChannelAttrs
  • set ChildOptions和ChildAttrs
  • 配置服务端pipeline
  • 添加连接器 add ServerBootstrapAcceptor image.png image.png

设置ChannelOptions和ChannelAttrs image.png 设置ChildOptions和ChildAttrs image.png 向pipeline中添加用户自定义的handler,这里就是前文我们所写的Server Handler image.png image.png 紧接着添加自定义pipeline之后会添加一个特殊的handler->ServerBootstrapAcceptor

其中它的四个参数就是我们自定义的几个参数,currentChildGroup就是我们在Server类中所写的workGroup

image.png image.png image.png image.png

注册selector

  • 代码入口 ->AbstractChannel.register()
  • 绑定线程 AbstractChannel.this.eventLoop = eventLoop
  • 进行实际注册 ->register0()
  • 调用jdk底层注册 ->doRegister()
  • 传播事件 invokeHandlerAddedIfNeeded和fireChannelRegistered

首先我们再次进入initAndRegister方法,然后点击Channel接口找到它实际执行的register方法,从而来到AbstractChannel的register() image.png image.png 绑定线程 image.png 继而向下看进入register0方法,为实际注册doRegister() image.png image.png image.png image.png 看完注册之后,回到register0方法,可以看到在执行doRegister()方法之后又执行了两个传播事件,运行程序后会发现,它其实按照顺序执行就是我们自定义的server handler中重写的两个方法 image.png image.png

端口绑定

  • 代码入口 ->AbstractChannel.bind()
  • dobind()
  • jdk底层绑定 ->javaChannel().bind()
  • fireChannelActive和readIfIsAutoRead

首先我们先进入之前分析initAndRegister那里,继注册初始化之后,进行端口绑定doBand0方法,而doband0方法会调用AbstractChannel下的Bind方法,因为AbstractChannel实现Channel接口,我们如上文查找register一样,点击Channel接口找到它实际执行的bing方法,从而来到AbstractChannel的bind()

在bind方法中可以看到doBind方法,我们点击进入选择NioSocketChannel,继而发现jdk底层绑定端口

image.png image.png image.png image.png image.png

在端口绑定完成之后会传播一个channelActive事件,进入之后找channelActive方法 fireChannelActive传播事件和前面那两个传播事件一样会执行serverhandler重写的方法,而readIfIsAutoRead则是表明绑定之后可以接收客户端了

image.png image.png

总结

image.png