(目录)
欢迎关注微信公众号:数据科学与艺术
心跳的两种模式是纯净的IdleStateHandler和纯净的IdleStateHandler+次数计时策略。
- 纯净的IdleStateHandler模式:使用参数设置的间隔空闲时间,如果超过这个时间,就认为心跳失败。
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
private static final int IDLE_TIME = 10; // 设置空闲时间为10秒
private IdleStateHandler idleStateHandler;
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.pipeline().addLast(idleStateHandler = new IdleStateHandler(0, 0, IDLE_TIME));
}
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if (idleStateEvent.state() == IdleState.READER_IDLE) {
// 心跳失败处理
ctx.close();
} else if (idleStateEvent.state() == IdleState.WRITER_IDLE) {
// 发送心跳消息
ctx.channel().writeAndFlush("heartbeat");
}
}
}
}
- 纯净的IdleStateHandler+次数计时策略模式:在一定时间内连续几次心跳失败才认为连接断开。这种模式考虑了心跳事件之间的时间间隔,如果间隔时间过长,就不会计算为心跳失败。
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
private static final int IDLE_TIME = 10; // 设置空闲时间为10秒
private static final int MAX_FAILURE_TIMES = 3; // 设置最大心跳失败次数为3次
private static final int MAX_FAILURE_INTERVAL = 5; // 设置心跳失败次数间隔为5秒
private IdleStateHandler idleStateHandler;
private int failureTimes;
private ScheduledExecutorService executorService;
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.pipeline().addLast(idleStateHandler = new IdleStateHandler(0, 0, IDLE_TIME));
failureTimes = 0;
executorService = Executors.newSingleThreadScheduledExecutor();
}
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if (idleStateEvent.state() == IdleState.READER_IDLE || idleStateEvent.state() == IdleState.WRITER_IDLE) {
failureTimes++;
if (failureTimes >= MAX_FAILURE_TIMES) {
// 心跳失败次数超过最大次数,断开连接
ctx.close();
} else {
// 重新计时
executorService.schedule(() -> {
failureTimes = 0;
}, MAX_FAILURE_INTERVAL, TimeUnit.SECONDS);
}
}
}
}
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
executorService.shutdown();
}
}
这两种模式都是通过空闲检查Handler来实现的,可以根据具体需求选择适合的模式来建立心跳机制。 基于Netty的实现,使用这两种模式之一可以建立心跳机制,保持与服务器的连接。