一、案例说明

  1. 编写一个 Netty 心跳检测机制案例,当服务器超过 3 秒没有读时,就提示读空闲
  2. 当服务器超过 5 秒没有写操作时,就提示写空闲
  3. 实现当服务器超过 7 秒没有读或者写操作时,就提示读写空闲
  4. 代码如下:

二、代码示例

MyServer

  1. public class MyServer {
  2. public static void main(String[] args) throws InterruptedException {
  3. // 创建两个线程
  4. NioEventLoopGroup bossGroup = new NioEventLoopGroup();
  5. NioEventLoopGroup workerGroup = new NioEventLoopGroup(3);
  6. try {
  7. ServerBootstrap serverBootstrap = new ServerBootstrap();
  8. serverBootstrap.group(bossGroup, workerGroup)
  9. .channel(NioServerSocketChannel.class)
  10. .handler(new LoggingHandler(LogLevel.INFO))// 在 bossGroup 增加一个日志处理器
  11. .childHandler(new ChannelInitializer<SocketChannel>() {
  12. @Override
  13. protected void initChannel(SocketChannel ch) throws Exception {
  14. ChannelPipeline pipeline = ch.pipeline();
  15. /**
  16. * 加入一个 netty 提供 IdleStateHandler
  17. * 1、IdleStateHandler 是 netty 提供的处理空闲状态的处理器
  18. * 2、Long readerIdleTime:表示多长时间没有读,就会发送一个心跳检测包,检测是否还是连接的状态
  19. * 3、Long writerIdleTime:表示多长时间没有写操作,就会发送一个心跳检测包,检测是否还是连接的状态
  20. * 4、Long allIdleTime:表示多长时间即没有读也没有写操作,就会发送一个心跳检测包,检测是否还是连接的状态
  21. *
  22. * 文档说明:
  23. * Triggers an IdleStateEvent when a Channel has not performed read, write, or both operation for a while.
  24. *
  25. * 5、当 IdleStateEvent 触发后,就会传递给管道的下一个handler去处理,通过调用下一个handler 的 userEventTriggered ,在该方法中去处理
  26. * IdleStateEvent(读空闲,写空闲,读写空闲)
  27. */
  28. pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS));
  29. // 加入一个对空闲检测进一步处理的 handler (自定义)
  30. pipeline.addLast(new MyServerHandler());
  31. }
  32. });
  33. // 启动服务器
  34. ChannelFuture channelFuture = serverBootstrap.bind(6699).sync();
  35. channelFuture.channel().closeFuture().sync();
  36. } finally {
  37. bossGroup.shutdownGracefully();
  38. workerGroup.shutdownGracefully();
  39. }
  40. }
  41. }

MyServerHandler

  1. public class MyServerHandler extends ChannelInboundHandlerAdapter {
  2. /**
  3. * @param ctx 上下文
  4. * @param evt 事件
  5. * @throws Exception
  6. */
  7. @Override
  8. public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
  9. if (evt instanceof IdleStateEvent) {
  10. // 将 evt 向下转型 IdleStateEvent
  11. IdleStateEvent event = (IdleStateEvent) evt;
  12. String eventType = null;
  13. switch (event.state()) {
  14. case READER_IDLE:
  15. eventType = "读空闲";
  16. break;
  17. case WRITER_IDLE:
  18. eventType = "写空闲";
  19. break;
  20. case ALL_IDLE:
  21. eventType = "读写空闲";
  22. break;
  23. }
  24. System.out.println(ctx.channel().remoteAddress() + "--超时时间--" + eventType);
  25. System.out.println("服务器做相应处理。。。。。");
  26. // 如果发生空闲,我们关闭通道
  27. ctx.channel().close();
  28. }
  29. }
  30. }