12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- package com.zhentao.information.handler;
- import io.netty.channel.ChannelHandler;
- 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;
- import org.springframework.stereotype.Component;
- /**
- * 心跳处理器
- * 处理客户端的心跳检测
- */
- @Slf4j
- @Component
- @ChannelHandler.Sharable
- public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
- private static final int MAX_MISSED_HEARTBEATS = 3;
- private int missedHeartbeats = 0;
- /**
- * 处理用户事件
- * 当触发IdleStateEvent时调用
- * @param ctx Channel上下文
- * @param evt 事件对象
- */
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- if (evt instanceof IdleStateEvent) {
- IdleStateEvent event = (IdleStateEvent) evt;
-
- if (event.state() == IdleState.READER_IDLE) {
- missedHeartbeats++;
- log.warn("读空闲,已错过 {} 次心跳", missedHeartbeats);
-
- if (missedHeartbeats >= MAX_MISSED_HEARTBEATS) {
- log.error("读空闲超时,关闭连接:{}", ctx.channel().id().asLongText());
- ctx.close();
- } else {
- // 发送心跳检测消息
- ctx.writeAndFlush("ping");
- }
- } else if (event.state() == IdleState.WRITER_IDLE) {
- // 发送心跳检测消息
- ctx.writeAndFlush("ping");
- }
- } else {
- super.userEventTriggered(ctx, evt);
- }
- }
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- if (msg instanceof String && "pong".equals(msg)) {
- // 收到心跳响应,重置计数器
- missedHeartbeats = 0;
- log.debug("收到心跳响应");
- } else {
- super.channelRead(ctx, msg);
- }
- }
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- log.info("连接断开:{}", ctx.channel().id().asLongText());
- super.channelInactive(ctx);
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- log.error("心跳处理器异常", cause);
- ctx.close();
- }
- }
|