项目路径:
E:\_1\java\project\java-project-learning\java-study\netty-std
git地址:
https://gitee.com/wei-yuliu/java-project-learning
代码
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //负责接收连接一个线程就能处理
// workerGroup:负责处理已建立连接的读写,线程数默认:cpu核心*2
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();//理解为服务器装配器
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)//基于Java NIO实现的服务器Channel
.option(ChannelOption.SO_BACKLOG, 128) // 等待连接的队列大小
.childOption(ChannelOption.SO_KEEPALIVE, true) // 保持长连接
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new EchoServerHandler());
}
});
class EchoServerHandler extends io.netty.channel.ChannelInboundHandlerAdapter {
@Override
public void channelRead(io.netty.channel.ChannelHandlerContext ctx, Object msg) {
String message = (String) msg;
System.out.println("[服务端] 收到客户端消息: " + message);
// 原样发回给客户端(回声)
ctx.writeAndFlush("ECHO: " + message);
}
}
ChannelFuture future = bootstrap.bind(8080).sync();
future.channel().closeFuture().sync();
Channel 分成两种,和NIO类似
NioServerSocketChannel//代表整个监听端口,例如:0.0.0.0:8080
NioSocketChannel//客户端的信息,ip和端口
option 和 childOption,配置Socket参数
-
ChannelOption.SO_BACKLO:表示操作系统等待服务器接受连接的队列容量。
-
ChannelOption.SO_KEEPALIVE:开启TCP KeepAlive。长连接。
option → NioServerSocketChannel
childOption → NioSocketChannel
初始化每条连接的Pipeline
childHandler: 每来一个新连接,都会执行一次 initChannel,创建处理对象,每个连接都有自己的pipeline。
这里SocketChannel是接口,按道理应该写成NioSocketChannel,但是后面如果Linux环境换成:EpollSocketChannel
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new EchoServerHandler());
}
});
向操作系统申请绑定8080端口。
异步操作,立即返回,所以要改成同步sync()
ChannelFuture future = bootstrap.bind(8080).sync();
等待服务器 socket 关闭
future.channel().closeFuture().sync();
future.channel()拿到的是服务器Channel:NioServerSocketChannel
closeFuture()还是异步的,改成同步sync()。一般除非主动关,不然不会执行这个。
完成Lesson 1后:
- Boss负责接受连接,Worker负责连接读写。
ServerBootstrap负责装配服务器。NioServerSocketChannel代表监听端口。- 每个客户端连接拥有自己的Channel和Pipeline。
- Inbound数据从Pipeline前向后传播。
- Outbound数据从Pipeline后向前传播。
- Decoder将字节转换成业务对象。
- Encoder将业务对象转换成字节。
bind()是异步操作,sync()负责等待结果。closeFuture().sync()让服务器持续运行。shutdownGracefully()负责释放Netty线程资源。