Netty服务端启动过程
(1)创建服务端Channel:调用JDK底层的API创建一个JDK的Channel,然后netty将其包装成自己的Channel,同时创建一些基本组件绑定在此Channel上
(2)初始化服务端Channel:初始化一些基本属性,以及添加一些逻辑处理器
(3)注册selector:Netty将JDK底层的Channel注册到事件轮询器selector上面
(4)端口绑定:最终也是调用底层JDK的API实现对本地端口的监听
bind()[用户代码入口]
initAndRegister()[初始化并注册]
newChannel()[创建服务端Channel]
init()[初始化服务端Channel]
AbstractChannel.register(channel)[注册selector]
AbstractUnsafe.bind()[端口绑定]
(1)创建服务端Channel
bind()[用户代码入口]
initAndRegister()[初始化并注册]
newChannel()[创建服务端Channel]:通过反射创建Channel,通过反射的方式调用NioServerSocketChannel的构造函数。
反射创建服务端Channel:
newSocket()[通过jdk来创建底层jdk channel]
NioServerSocketChannelConfig()[tcp参数配置类]
AbstractNioChannel()
configureBlocking(false)[阻塞模式]:false为非阻塞
AbstractChannel() [创建id,unsafe,pipeline]
注:AbstractChannel() 服务端和客户端的Channel都是继承自AbstractChannel,AbstractChannel是对Channel的一个抽象。id是对应每一条Channel的唯一标识,unsafe是跟tcp相关的读写(底层的一个操作,netty自己用到的类),pipeline是服务端和客户端逻辑相关的一个逻辑链
(2)初始化服务端Channel
init()[初始化入口]
set ChannelOptions,ChannelAttrs
set ChildOptions,ChildAttrs
config handler[配置服务端pipeline]
add ServerBootstrapAcceptor[添加连接器]
总结:保存用户自定义的一些属性,通过这些属性创建一个连接接入器,连接接入器每次accept新的连接之后,都会使用这些属性对新的连接做一些配置。
(3)注册selector
AbstractChannel.register(channel)[入口]
this.eventLoop=eventLoop[绑定线程]
register0()[实际注册]
doRegister()[调用jdk底层注册]
invokeHandlerAddedIfNeeded()[事件的回调]
fileChannelRegistered()[传播事件] 将channel注册成功事件传播到用户的代码中
(4)端口绑定
AbstractUnsafe.bind()[入口]
doBind()
javaChannel().bind()[jdk底层绑定]
pipeline.fireChannelActive()[传播Active事件]
HeadContext.readIfIsAutoRead()
注: HeadContext.readIfIsAutoRead()将之前注册到seletor上的事件重新绑定为一个accept事件,这样新连接进来,selector就会轮询到,可将这个事件交给netty来处理
原文地址:https://www.cnblogs.com/chanaichao/p/9334377.html