一、 pom.xml 所需依赖
MessagePack是编解码工具,稍后介绍
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack -->
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
二、 netty配置类
2.1 启动服务类
创建两个EventLoopGroup
实例,实际是两个Reactor线程组,一个用于服务端接收客户端的连接,一个用于进行socketChannel的网络读写
ServerBootstrap
对象是netty用于启动NIO服务端的辅助启动类,目的是降低服务端的开发复杂度
group
方法将两个NIO线程组当做入参传递到ServerBootstrap
中
接着设置创建的Channel为NioServerSocketChannel
然后配置TCP参数,此处将他的backlog设置为128
然后绑定I/O事件的处理类ServerChannelInitializer
,这个稍后看实现,主要用于处理网络I/O事件,例如对消息进行编解码、记录日志、处理业务等
可以通过childOption
针对客户端进行一些配置,例如检测心跳状态、设置是否一次发送等
private final EventLoopGroup bossGroup = new NioEventLoopGroup();
private final EventLoopGroup workerGroup = new NioEventLoopGroup();
private Channel channel;
@Autowired
private ChannelCache channelCachel;
public ChannelFuture run(InetSocketAddress address) {
ChannelFuture f = null;
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128)
.childHandler(new ServerChannelInitializer()).childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true);
f = b.bind(address).sync();
channel = f.channel();
} catch (Exception e) {
log.error("Netty start error:", e);
} finally {
if (f != null && f.isSuccess()) {
log.info("Netty server listening " + address.getHostName() + " on port " + address.getPort()
+ " and ready for connections...");
} else {
log.error("Netty server start up Error!");
}
}
return f;
}
2.2 netty退出
public void destroy() {
log.info("Shutdown Netty Server...");
channelCachel.flushDb();
if (channel != null) {
channel.close();
}
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
log.info("Shutdown Netty Server Success!");
}
其中channelCachel
是自定义的一个保存通道信息的工具类,稍后介绍
2.3 I/O事件处理类
主要包括对消息的编解码、设置心跳超时以及设置业务处理类
本例中,服务端只检测读空闲时间
编解码器和业务处理类稍后展示
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws E