Netty服务器监听读写超时
跟客户端监听连接断开时的处理一样,既添加Netty内置的处理,同时也需要添加自定义处理器。
先来看Netty内置的处理。
ChannelPipeline pipeline = channel.pipeline();
//添加Netty内置的空闲状态检测Handler,60秒没有读写,则触发超时事件
pipeline.addLast(new IdleStateHandler(60, 60, 60, TimeUnit.SECONDS));
上面代码添加了一个Netty内置的处理器:IdleStateHandler
IdleStateHandler
的构造函数有4个参数:
public IdleStateHandler(long readerIdleTime, // 读空闲时间long writerIdleTime, // 写空闲时间 long allIdleTime, // 所有类型空闲时间TimeUnit unit // 时间单位
)
上面的配置实现:
readerIdleTime = 60: 60秒没有读取操作触发读空闲
writerIdleTime = 60: 60秒没有写入操作触发写空闲
allIdleTime = 60: 60秒既没有读也没有写操作触发全部空闲
TimeUnit.SECONDS: 时间单位为秒
工作机制
1. 检测原理
Netty会为每个Channel启动定时任务
定期检查最后一次读写操作的时间
如果超过设定时间没有相应操作,就触发对应事件
2. 事件触发
当超时发生时,会触发 userEventTriggered
事件,userEventTriggered
在下面自定义服务器心跳检测处理器会有说明。
由于IdleStateHandler的职责仅仅负责检测空闲状态,不处理具体业务逻辑,因此我们需要定义一个自定义的处理器,用于接收空闲事件并执行具体的业务处理逻辑。
下面创建一个服务器心跳检测处理器
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;/*** @author: * @Desc:服务器端心跳包处理器* @create: 2025-10-03 11:24**/
@Slf4j
public class MyServerHeartBeatHandler extends ChannelInboundHandlerAdapter {// 心跳包处理@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if (evt instanceof IdleStateEvent) {IdleStateEvent event = (IdleStateEvent) evt;IdleState state = event.state();switch (state) {case READER_IDLE:log.info("客户端长时间没有发送数据,关闭连接");ctx.close();break;case WRITER_IDLE:log.info("客户端长时间没有写数据,发送心跳包");ctx.writeAndFlush("heartbeat");break;case ALL_IDLE:log.info("客户端长时间没有任何活动,关闭连接");ctx.close();break;default:break;}}super.userEventTriggered(ctx, evt);}
}
最后在Netty服务器添加该处理器。