Netty心跳机制
服务器要知道每个Socket是否活跃;要不断监听每个Channel处于什么状态;
实现:
- 服务器超过3s没有读,提示读空闲;
- 服务器超过5s没有写,提示写空闲;
- 超过7s没有读写,提示读写空闲;
-
配置ServerBootstrap:
serverBootstrap.group(bossGroup, workerGroup) // boss关联日志服务器 .handler(new LoggingHandler(LogLevel.INFO)) // worke添加Handler,初始化Channel .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // 添加检测空闲状态的Handler pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS)); });
-
IdleStateHandler:添加此Handler即开启心跳机制;
IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit)
三个主要参数:
- readerIdleTime:多久Server没有读取Client数据;
- writerIdleTime:多久Server没有发送给Client数据
- allIdleTime:多久Server既没有读,也没有写数据给Client;
上述的三种事件,在满足一定条件后,会触发
userEventTriggered(自定义Handler重写的方法)
方法,做出相应的处理; -
实现
userEventTriggered
:这三种事件:(READER_IDLE,WRITER_IDLE,ALL_IDLE)在
IdleState
枚举类下public enum IdleState { READER_IDLE, WRITER_IDLE, ALL_IDLE }
通过
switch
语句判断事件类型,做出相应的动作:public class ServerHandler extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { // 拿到事件 IdleStateEvent event = (IdleStateEvent) evt; String eventType = null; switch (event.state()) { case READER_IDLE: eventType = "读空闲"; break; case WRITER_IDLE: eventType = "写空闲"; break; case ALL_IDLE: eventType = "读写空闲"; // 如果发生读写空闲,将通道关闭 ctx.channel().close(); break; } SocketAddress socketAddress = ctx.channel().remoteAddress(); System.out.println("[" + socketAddress + "] 触发:" + eventType); } } }