欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!
    关于心跳我们在长链接的开发中一般都是会遇到的,因为是长链接所以需要定时发送心跳保持连接的活跃。当服务端检测不到客户端的心跳之后就会释放资源,这个操作是一个很重要的操作。

    如果你处理过原生socket的心跳检测机制,你会发现那是一个比较麻烦的处理。你需要起一个线程或者定时任务来不停的检测连接是否有心跳上送,如果没有心跳你就需要释放资源,关闭socket或者尝试重连机制。

    Netty为我们提供了一个“IdleStateHandler”闲置状态处理器。如果在一定的时间内没有读、写或者两者都没有的操作将会被触发这个处理器的事件。

    关于“IdleStateHandler”我们需要设置一些参数,一般的设置为:


public IdleStateHandler(long readerIdleTime, long writerIdleTime,long allIdleTime,TimeUnit unit) {this(false, readerIdleTime, writerIdleTime, allIdleTime, unit);
}

    “readerIdleTime”:读取数据的超时时间,也就是说连接建立之后在这个readerIdleTime时间内没有读取到数据就会被触发。

    “writerIdleTime”:写超时事件,也就是说在连接建立之后在writerIdleTime时间内没有往外面写任何数据。

    “allIdleTime”:读写超时事件,也就是说在连接建立之后在allIdleTime时间内既没有发生读的事件,也没有发生写的事件。

    “unit”:前面参数的时间单位,是以分钟啊,还是秒啊,或者是小时为单位进行一次检测数据。

    如果参数设置成0的话,那么是“无效”的,也就是说netty会忽略到这个配置。接下来看看心跳检测的示例。

public class HeartBeatServer {public static void main(String[] args) {EventLoopGroup boss = new NioEventLoopGroup();EventLoopGroup worker = new NioEventLoopGroup();try {ServerBootstrap server = new ServerBootstrap();server.group(boss, worker).channel(NioServerSocketChannel.class).childHandler(new HeartBeatServerInitializer());ChannelFuture channelFuture = server.bind(9999).sync();channelFuture.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {boss.shutdownGracefully();worker.shutdownGracefully();}}
}
public class HeartBeatServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new LineBasedFrameDecoder(1024));pipeline.addLast(new StringDecoder());pipeline.addLast(new StringEncoder());pipeline.addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));pipeline.addLast(new HeartBeatServerHandler());}
}

public class HeartBeatServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println("接收到信息: " + msg);}@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {IdleStateEvent event = (IdleStateEvent) evt;switch (event.state()) {case READER_IDLE:System.out.println("读空闲");break;case WRITER_IDLE:System.out.println("写空闲");break;case ALL_IDLE:System.out.println("读写空闲");break;default:throw new IllegalStateException("非法状态!");}}
}

    假设我们写一个客户端不进行数据的发送,看看会触发什么效果:

public class HeartBeatClient {public static void main(String[] args) {EventLoopGroup worker = new NioEventLoopGroup();try {Bootstrap client = new Bootstrap();client.group(worker).channel(NioSocketChannel.class).handler(new HeartBeatClientInitializer());Channel channel = client.connect("localhost", 9999).sync().channel();channel.closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {worker.shutdownGracefully();}}
}
public class HeartBeatClientInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new LineBasedFrameDecoder(1024));pipeline.addLast(new StringEncoder());pipeline.addLast(new StringDecoder());pipeline.addLast(new HeartBeatClientHandler());}
}
public class HeartBeatClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {}
}

    启动服务端和客户端,等过一段时间你会发现:


读空闲
读空闲
读空闲

    也许你会疑问,被触发了之后该怎么办呢?其实,想怎么办就怎办!也许你已经发现了,在事件被触发的方法中有一个比较重要的“ChannelHandlerContext”。这个“ChannelHandlerContext”是连接ChannelHandler和ChannelPipeline的重要上下文,有了它你就可以对channel进行操作了!

    那么将之前的代码进行一下修改,没有读取到数据就断开连接。

public class HeartBeatServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println("接收到信息: " + msg);}@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {IdleStateEvent event = (IdleStateEvent) evt;switch (event.state()) {case READER_IDLE:System.out.println("读空闲");ctx.channel().close();break;case WRITER_IDLE:System.out.println("写空闲");break;case ALL_IDLE:System.out.println("读写空闲");break;default:throw new IllegalStateException("非法状态!");}}
}

    你会发现就添加了一行代码。

ctx.channel().close();

    再来试着运行一下服务端和客户端:都运行的时候可以到两个进程在运行

    等过了5秒服务端打印出一句话之后就不会再继续打印了。

    再看看进程就剩一个客户端了。


    其实不仅如此,你完全可以结合业务对心跳检测信息做出处理。因为你已经拿到了它对应的“ChannelHandlerContext”,你可以利用它写数据,广播数据,关闭连接等操作。客户端也可以根据服务端上送的心跳进行重连等操作!

    欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!

Netty-心跳检测的作用和实现方法相关推荐

  1. Netty(八) Netty心跳检测机制

    1.什么是长链接和短链接 在HTTP/1.0中默认使用短连接.也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接.当客户端浏览器访问的某个HTML或其他类型的Web页中 ...

  2. Netty -Netty心跳检测机制案例,Netty通过WebSocket编程实现服务器和客户端长链接

    Netty心跳检测机制案例 案例要求 编写一个Netty心跳检测机制案例,当服务器超过3秒没有读时,就提示读空闲 当服务器超过5秒没有写操作时,提示写空闲 服务器超过7秒没有读或者写操作时,就提示读写 ...

  3. Netty心跳检测机制

    一.Netty心跳检测机制 心跳:即在 TCP 长连接中,客户端和服务器之间定期发送的一种特殊的数据包,通知对方自己还在线,以确保 TCP 连接的有效性. 在 Netty 中,实现心跳机制的关键是 I ...

  4. Netty 心跳检测机制

    心跳检测机制 目的:就是用于检测 检测通信对方是否还"在线",如果已经断开,就要释放资源 或者 尝试重连. 大概的实现原理就是:在服务器和客户端之间一定时间内没有数据交互时, 即处 ...

  5. Netty心跳检测代码及源码流程

    心跳检测是指在TCP长连接中,客户端和服务端定时发送和接受简单数据,确保服务正常,在Netty中,对心跳检测进行了很好的封装,下面我们来看一下心跳检测的实现和源码 Netty通过什么来实现心跳? Id ...

  6. netty的编解码、粘包拆包问题、心跳检测机制原理

    文章目录 1. 编码解码器 2. 编解码序列化机制的性能优化 3. Netty粘包拆包 4. Netty心跳检测机制 5. Netty断线自动重连实现 1. 编码解码器 当你通过netty发送或者接受 ...

  7. Netty学习(七):心跳检测机制

    一.什么是心跳检测机制 所谓心跳, 即在 TCP 长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 心跳机制主要是客户端和服务端长时间连 ...

  8. Netty教程07:心跳检测机制

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

  9. Netty 心跳机制及断线重连

    1.心跳检测 心跳检测是在TCP长连接中,客户端和服务端定时向对方发送数据包通知对方自己还在线,保证连接的有效性的一种机制. 为什么使用心跳检测? 假死:如果底层的TCP连接(socket连接)已经断 ...

最新文章

  1. django学习之路(五)站点管理admin - django - 一直很安静 - Powered by Discuz!
  2. php 定义title,HTML5中对title属性的定义与规定
  3. ActionScript3.0程序开发工具
  4. 现在有一个map集合如下: Map<Integer,String> map = new HashMap<Integer, String>(); map.put(1, “
  5. 华南师范大学计算机学院重修,选修课挂科有什么影响 还需要重修吗
  6. 风控的这些工作机会看起来挺没用
  7. 怎样使用libmad
  8. mexopenCV的配置学习过程
  9. 数商云医药行业SCM供应链管理系统应用场景、运用模式
  10. NAS个人云存储服务器搭建
  11. 校验码(循环冗余校验码)
  12. 使用备份工具mysqldump备份数据库
  13. 杭州证历本如何使用_药店也可以用
  14. python里使用正则表达式搜索单词
  15. 威斯康星麦迪逊计算机科学专业,威斯康星大学麦迪逊分校计算机科学专业申请条件汇总...
  16. Excel | 替换特定大小的单元格值(如:小于5000的值)为指定值
  17. 欧姆龙PLC和FANUC发那科DeviceNet通讯
  18. php中常用的输出语句及其区别
  19. Java 自学路线图之 Java 进阶自学
  20. 将Openfire中的MUC改造成类似QQ群一样的永久群

热门文章

  1. 软件项目开发分工贡献占比
  2. 物联网LoRa系列-8:LoRa终端应用程序开发环境的搭建
  3. 3D模型【厕纸筒/厕纸架】
  4. 每天一道大厂SQL题【Day03】订单量统计
  5. Cobalt Strike折腾踩坑填坑记录
  6. 微信小程序异常,this.setDate is not a function报错求解
  7. Android MVC框架 - Baymax
  8. 微信小程序——实现蓝牙设备搜索及连接功能
  9. Windows下谷歌浏览器快捷键方式汇总
  10. 论文阅读 [TPAMI-2022] Multiview Clustering: A Scalable and Parameter-Free Bipartite Graph Fusion Method