文章目录
- 1.IdleStateHandler介绍
- 2.IdleStateHandler源码解析
- 3.IdleStateHandler总结
1.IdleStateHandler介绍
Netty服务端心跳机制: IdleStateHandler, 这个类可以对三种类型的心跳检测。
@ChannelHandler.Sharable
public class IdleHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(IdleHandler.class);
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object paramObject) throws Exception {
LOG.info("userEventTriggered");
if (paramObject instanceof IdleStateEvent) {
IdleState state = ((IdleStateEvent) paramObject).state();
if (state == IdleState.ALL_IDLE) {
//关闭连接
ctx.channel().close();
}
} else {
super.userEventTriggered(ctx, paramObject);
}
}
}
IdleHandler继承了ChannelInboundHandlerAdapter, 载了userEventTriggered方法, 执行了关闭连接的逻辑
2.IdleStateHandler源码解析
- readerIdleTime:为读超时时间(即测试端一定时间内未接受到被测试端消息
- writerIdleTime:为写超时时间(即测试端一定时间内向被测试端发送消息)
- allIdleTime:所有类型的超时时间
这个类是ChannelHandler, 会被加载如ChannelPipeline。
让channelPipe中的下一个handler处理channelRead方法。
fireChannelRead用法: fireChannelRead表示传递消息至下一个处理器, 因为Pipeline的原因, 有 一个链式的处理队列, 消息为队列的头处理器进入。
比如如果A, B, C处理器, 如果A处理器没有fireChannelRead方法, 那么B, C不会接受到消息。
IdleStateHandler的精髓。
private void initialize(ChannelHandlerContext ctx) {
// Avoid the case where destroy() is called before scheduling timeouts.
// See: https://github.com/netty/netty/issues/143
switch (state) {
case 1:
case 2:
return;
}
state = 1;
initOutputChanged(ctx);
lastReadTime = lastWriteTime = ticksInNanos();
if (readerIdleTimeNanos > 0) {
readerIdleTimeout = schedule(ctx, new ReaderIdleTimeoutTask(ctx),
readerIdleTimeNanos, TimeUnit.NANOSECONDS);
}
if (writerIdleTimeNanos > 0) {
writerIdleTimeout = schedule(ctx, new WriterIdleTimeoutTask(ctx),
writerIdleTimeNanos, TimeUnit.NANOSECONDS);
}
if (allIdleTimeNanos > 0) {
allIdleTimeout = schedule(ctx, new AllIdleTimeoutTask(ctx),
allIdleTimeNanos, TimeUnit.NANOSECONDS);
}
}
创建时间间隔为readerIdleTime的定时任务。触发了一个Task, ReaderIdleTimeoutTask。
用当前时间减去最后一次channelRead方法调用的时间, 假如这个结果是6s, 说明最后一次调用channelRead已经是6s之前的事情了, 设置为5s, 那么nextDelay为-1, 说明超时了。执行③处代码, 触发channelIdle(), 执行fireUserEventTriggered(), 下一个处理器的userEventTriggered()
自定义的userEventTriggered方法, 在自带的IdleStateHandler处理器, 在心跳检测超时时, 最终会执行下一个handler的userEventTriggered方法来处理。
3.IdleStateHandler总结
IdleStateHandler这个类会根据你设置的超时参数的类型和值, 循环去检测channelRead和write方法多久没有被调用了, 如果时间超过设置的时间的话, 触发对应的事件, channelRead, channelActive, channelIdle方法
- 如果超时了, 则会调用userEventTriggered方法, 且会告诉你超时的类型
- 如果没有超时, 则会循环定时检测, 除非你将IdleStateHandler移除Pipeline