Netty心跳检测机制案例
要求:
- 编写一个 Netty心跳检测机制案例, 当服务器超过3秒没有读时,就提示读空闲
- 当服务器超过5秒没有写操作时,就提示写空闲
- 实现当服务器超过7秒没有读或者写操作时,就提示读写空闲
Server:
package com.atguigu.netty.NettyHeartBeat;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.concurrent.TimeUnit;
/**
* @Description: ···
* @author: Freedom
* @QQ: 1556507698
* @date:2022/6/25 17:23
*/
public class HeartServer {
public static void main(String[] args) throws InterruptedException {
//线程组
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
//在bossGroup 关联一个日志处理器
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//加入Netty提供的IdleStateHandle
//TODO 处理空闲状态的处理器
//当IdleStateEvent 触发后就会传递给管道(pipeline)的下一个Handle去处理 通过回调下一个handle 的 UserEventTiggered 方法去处理
/*long readerIdleTime,多长时间没有读取操作 Server没有读取Client发送的数据 就会发送一个心跳检测包检测是否还是连接状态
* long writerIdleTime,多长时间没有写操作 Server没有读取Client发送的数据 就会发送一个心跳检测包检测是否还是连接状态
* long allIdleTime, 表示多长时间没有 读 写 操作了 而后发送心跳检测
* TimeUnit unit 时间单位 */
pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS));
//TODO 加入一个对空闲检测进一步处理的Handle(自定义)
pipeline.addLast(new HeartServerhandle());
}
});
//启动服务器
ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
//监关闭事件
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
ServerHandle
package com.atguigu.netty.NettyHeartBeat;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
/**
* @Description: ···
* @author: Freedom
* @QQ: 1556507698
* @date:2022/6/25 17:46
*/
public class HeartServerhandle extends ChannelInboundHandlerAdapter {
/**
* 当IdleStateEvent 触发后就会传递给管道(pipeline)的下一个Handle去处理 通过回调下一个handle 的 UserEventTiggered 方法去处理
* @param ctx 上下文
* @param evt 事件
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//判断是不是IdleStateEvent类型
if (evt instanceof IdleStateEvent){
//将evt 向下转型 IdleStateEvent
IdleStateEvent event = (IdleStateEvent) evt;
//判断是什么事件心跳检测不通过
//READER_IDLE 读空闲, WRITER_IDLE 写空闲, ALL_IDLE 读写空闲
String eventType = "";
switch (event.state()){
case READER_IDLE: eventType = "读空闲"; break;
case WRITER_IDLE: eventType = "写空闲"; break;
case ALL_IDLE: eventType = "读写空闲"; break;
}
System.out.println("通道: " + ctx.channel().remoteAddress()+eventType + "超时事件发生");
//如果发生空闲了直接关闭通道 空闲事件只会发生一次 谁心跳短谁先发生
ctx.channel().close();
}
}
}
复用之前客户端测试即可
结果:
六月 25, 2022 5:59:13 下午 io.netty.handler.logging.LoggingHandler channelRegistered
信息: [id: 0x82bc9da5] REGISTERED
六月 25, 2022 5:59:13 下午 io.netty.handler.logging.LoggingHandler bind
信息: [id: 0x82bc9da5] BIND: 0.0.0.0/0.0.0.0:7000
六月 25, 2022 5:59:13 下午 io.netty.handler.logging.LoggingHandler channelActive
信息: [id: 0x82bc9da5, L:/0:0:0:0:0:0:0:0:7000] ACTIVE
六月 25, 2022 6:00:42 下午 io.netty.handler.logging.LoggingHandler channelRead
信息: [id: 0x82bc9da5, L:/0:0:0:0:0:0:0:0:7000] READ: [id: 0xae0eee37, L:/127.0.0.1:7000 - R:/127.0.0.1:49403]
六月 25, 2022 6:00:42 下午 io.netty.handler.logging.LoggingHandler channelReadComplete
信息: [id: 0x82bc9da5, L:/0:0:0:0:0:0:0:0:7000] READ COMPLETE
通道: /127.0.0.1:49403读空闲超时事件发生
通道: /127.0.0.1:49403写空闲超时事件发生
通道: /127.0.0.1:49403读空闲超时事件发生
通道: /127.0.0.1:49403读写空闲超时事件发生
通道: /127.0.0.1:49403读空闲超时事件发生
通道: /127.0.0.1:49403写空闲超时事件发生
通道: /127.0.0.1:49403读空闲超时事件发生
通道: /127.0.0.1:49403读写空闲超时事件发生
进程已结束,退出代码为 -1