Netty心跳检测

Netty心跳检测

Netty给我们提供三个Handler,分别是IdleStateHandler、ReadTimeoutHandler、WriteTimeOutHandler,主要目的是检查对方是否还在线

为什么需要心跳机制
  • TCP协议适用于客户端数量相对较少,并且频繁通信的业务场景;HTTP协议使用与客户端数量比较大的业务场景;HTTP是短链接,请求完成后会释放连接资源,不占用服务器资源,但是TCP连接成功则可以多次请求,不会释放,除非特殊原因导致连接失败

  • 长链接不会释放链接资源,那么很多客户端只是完成了连接,但是没有实际的业务请求操作,那么服务器的资源还是被占用,导致服务器性能下降。

三个核心类
IdleStateHandler 当连接空闲时间(读或写)太长时,将触发 IdleStateEvent 事件,可以通过 ChannelInboundHandler 中重写 userEventTrigged 方法来处理该事件。
ReadTimeoutHandler 如果在指定的时间之内没有发生读事件,就会抛出这个异常,并且自动关闭连接。可以在 exectionCaught 方法中处理这个异常。
WriteTimeoutHandler 如果在指定的时间之内没有发生写事件,抛出次异常,并且关闭连接。可以在 exectionCaught 方法中处理这个异常。

服务端

 pipeline.addLast(new LoggingHandler(LogLevel.DEBUG));

 //5秒钟之内没有 读事件 则断开连接
 pipeline.addLast(new ReadTimeoutHandler(5,TimeUnit.SECONDS));
 //字符串解码器
 pipeline.addLast(new StringDecoder(Charset.forName("GBK")));

 //字符串编码器
 pipeline.addLast(new StringEncoder(Charset.forName("GBK")));

 //业务Handler
 pipeline.addLast(new HeartBeatHandler());


public class HeartBeatHandler extends ChannelInboundHandlerAdapter {
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 System.out.println("channelRead>>>"+msg+">>>"+ LocalDateTime.now());
 }

 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
 System.out.println("exceptionCaught>>>"+cause.getMessage());
 }
}

客户端


ch.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
 // 解码转String,注意调整自己的编码格式GBK、UTF-8
ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));

 //实例:延迟 1 秒钟,每个 15 秒钟往服务端发送一次 hello world。
 //心跳检测http://www.imooc.com/wiki/nettylesson/netty25.html
 f.channel().eventLoop().scheduleWithFixedDelay(() -> {
 f.channel().writeAndFlush("hello world!");
 }, 1, 15, TimeUnit.SECONDS);

代码说明

  • 客户端每个15秒发送一次数据,

  • 服务端如果5秒之内没有读事件,则自动端口连接

  • 因为每次都是隔15秒发送,客户端每次发送的数据都是超时了,因此,连接会被断开

FRCLc.png

更改代码

 f.channel().writeAndFlush("hello world!");
 }, 1, 1, TimeUnit.SECONDS);

服务端执行结果

FRVVh.png

参考
慕课网Netty心跳检测

你可能感兴趣的:(Netty心跳检测)