zoukankan      html  css  js  c++  java
  • 【Netty】心跳机制

    Netty心跳机制

    服务器要知道每个Socket是否活跃;要不断监听每个Channel处于什么状态;

    实现:

    • 服务器超过3s没有读,提示读空闲;
    • 服务器超过5s没有写,提示写空闲;
    • 超过7s没有读写,提示读写空闲;
    1. 配置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));
      });
      
    2. IdleStateHandler:添加此Handler即开启心跳机制;

      IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit)
      

      三个主要参数:

      • readerIdleTime:多久Server没有读取Client数据;
      • writerIdleTime:多久Server没有发送给Client数据
      • allIdleTime:多久Server既没有读,也没有写数据给Client;

      上述的三种事件,在满足一定条件后,会触发userEventTriggered(自定义Handler重写的方法)方法,做出相应的处理;

    3. 实现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);
              }
          }
      }
      

  • 相关阅读:
    allocation size overflow
    数据库隔离级别深入理解(ORACLE)
    查看Orcale数据里的表是否有变化
    意外发现抽象类的构造器
    C语言学习快速笔记
    由javascript的闭包引申到程序语言编译上的自由变量作用域的考量
    easyui的datagrid的列checkbox自定义增加disabled选项
    数据库连接不关闭造成的问题以及RowSet的使用
    Quartz的JobDetail没有触发器指向时会被删除的问题
    发现浏览器开发工具的一个小问题
  • 原文地址:https://www.cnblogs.com/mussessein/p/12617330.html
Copyright © 2011-2022 走看看