经过学习前面的内容,你们基本可使用netty来开发程序了,本文再补充一下心跳检测部分,属因而完善功能的内容了。数据库
大部分人听到心跳链接这个名词都是在数据库链接池上,他的主要做用是发现长期不用的链接,就关闭掉,减轻服务器的链接压力。在不少异常场合,例如客户端强行杀掉等等,形成了程序不是正常退出的,服务器端的socket不少都是客户端发消息而后响应的这种模式,客户端不发送了,只有服务端再经过socket发送消息时才知道,原来已经链接断了,并且还一直浪费socket资源(socket是算文件描述符数的,不少系统都有文件描述符的个数限制)。心跳检测就是为了防止这种浪费的手段,要求双方定时必须收到消息,不然认为应该链接断开。这个场景在现实生活中也很场景,你们约定什么时间见面,约定时间到了,人没来,最多等5分钟就走,只要5分钟内收到信息,就能够选择继续等仍是直接走,并不会无限期的等待下去。服务器
netty提供了心跳检测类IdleStateHandler。他的三个参数,分别是读超时时间,写超时时间,读写超时时间。网络
通常状况下,服务端是看读超时,就是看客户端多久没有发送消息了,这个须要根据业务来,大部分状况都是这样的。socket
ch.pipeline().addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(new ServerHeartBeat());
这里检测到有超时,就会发送事件,咱们还须要作一个事件处理,时间0表示不监控。ide
public class ServerHeartBeat extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) {//超时事件 IdleStateEvent idleEvent = (IdleStateEvent) evt; if (idleEvent.state() == IdleState.READER_IDLE) {//读 ctx.channel().close(); } else if (idleEvent.state() == IdleState.WRITER_IDLE) {//写 } else if (idleEvent.state() == IdleState.ALL_IDLE) {//所有 } } super.userEventTriggered(ctx, evt); } }
咱们如今的场景只对读作处理,为了方便,这里列出了全部的事件。学习
咱们能够启动telnet来测试一下,看看10秒不发送数据,会不会形成链接断开。测试
客户端通常是写超时,就是多久没有写数据了,此时就须要发送一个心跳包,告诉服务器端本身还在链接着。心跳包其实就是一个自定义的内容,通常不拿有意义的消息来发送,会选择比较短的内容来保证不会形成网络压力。netty
ch.pipeline().addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(new ClientHeartBeat());
客户端监听写事件code
public class ClientHeartBeat extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent idleEvent = (IdleStateEvent) evt; if (idleEvent.state() == IdleState.READER_IDLE) { } else if (idleEvent.state() == IdleState.WRITER_IDLE) { ctx.channel().writeAndFlush("hello"); } else if (idleEvent.state() == IdleState.ALL_IDLE) { } } super.userEventTriggered(ctx, evt); } }
当发现超时的时候,就去写一条信息。事件
启动这样的客户端就保证了不被服务端的检测关闭了。
心跳检测是经常使用的方式对链接作处理,使用netty提供的IdleStateHandler帮咱们省去了本身维护的状况。本文举出的场景是比较常见的一种,并非全部的都得这么写, 也有服务端监控写事件,客户端监控读事件,或者所有都监控的场景,这些须要根据业务来分析制做。