1.Netty服务端创建时序图
步骤1代码:
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
首先通过构造函数创建ServerBootstrap实例,通常会创建两个EventLoopGroup(也可以只创建一个并共享),NioEventLoopGroup实际就是Reactor线程池,负责调度和执行客户端的接入、网络的读写事件的处理、用户自定义任务和定时任务的执行。通过ServerBootstrap的group方法将两个EventLoopGroup 实例传入,代码如下:
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;
}
}
其中父NioEventLoopGroup被传入父类构造函数中,代码如下:
public B group(EventLoopGroup group) {
if (group == null) {
throw new NullPointerException("group");
} else if (this.group != null) {
throw new IllegalStateException("group set already");
} else {
this.group = group;
return this;
}
}
该方法会被客户端和服务端重用,用于设置工作I/O线程,执行和调度网络事件的读写。
线程组和线程类型设置完成后,需要设置服务端Channel用于端口和客户端链路接入。Netty通过Channel工厂类来创建不同类型的Channel,对于服务端,需要创建NioServerSocketChannel。所以,通过指定Channel类型的方式创建Channel工厂。 ServerBootstrapChannelFactory是ServerBootstrap的内部静态类,职责是根据Channel的类型通过反射创建Channel的实例,服务端需要创建的是NioServerSocketChannel实例。
.channel(NioServerSocketChannel.class)
指定NioServerSocketChannel后,需要设置TCP的一些参数,作为服务端,主要是要设置TCP的backlog参数,底层C的对应接口定义如下:
int listen(int fd,int backlog);
然后,绑定客户端hander,实现ChannelInitializer,
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new TimeServerHandler());
}
});
绑定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
等待服务端监听端口关闭
f.channel().closeFuture().sync();
优雅退出,释放线程资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
开始启动方法
public static void main(String[] args) {
int port = 8081;
if(args!=null && args.length>0){
try {
port = Integer.valueOf(args[0]);
}catch (NumberFormatException e){
//采用默认值
}
}
new TimeServer().bind(port);
}