从零开始学netty——心跳检测

通过学习前面的内容,大家基本可以使用netty来开发程序了,本文再补充一下心跳检测部分,属于是完善功能的内容了。

为什么要有心跳检测

大部分人听到心跳连接这个名词都是在数据库连接池上,他的主要作用是发现长期不用的连接,就关闭掉,减轻服务器的连接压力。在很多异常场合,例如客户端强行杀掉等等,造成了程序不是正常退出的,服务器端的socket很多都是客户端发消息然后响应的这种模式,客户端不发送了,只有服务端再通过socket发送消息时才知道,原来已经连接断了,而且还一直浪费socket资源(socket是算文件描述符数的,很多系统都有文件描述符的个数限制)。心跳检测就是为了防止这种浪费的手段,要求双方定时必须收到消息,否则认为应该连接断开。这个场景在现实生活中也很场景,大家约定什么时间见面,约定时间到了,人没来,最多等5分钟就走,只要5分钟内收到信息,就可以选择继续等还是直接走,并不会无限期的等待下去。

netty的心跳检测

netty提供了心跳检测类IdleStateHandler。他的三个参数,分别是读超时时间,写超时时间,读写超时时间。

服务端超时

一般情况下,服务端是看读超时,就是看客户端多久没有发送消息了,这个需要根据业务来,大部分情况都是这样的。

						ch.pipeline().addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS));
		                               ch.pipeline().addLast(new ServerHeartBeat());

这里检测到有超时,就会发送事件,我们还需要做一个事件处理,时间0表示不监控。

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秒不发送数据,会不会造成连接断开。

客户端超时

客户端一般是写超时,就是多久没有写数据了,此时就需要发送一个心跳包,告诉服务器端自己还在连接着。心跳包其实就是一个自定义的内容,一般不拿有意义的消息来发送,会选择比较短的内容来保证不会造成网络压力。

					ch.pipeline().addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS));
		                        ch.pipeline().addLast(new ClientHeartBeat());

客户端监听写事件

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帮我们省去了自己维护的情况。本文举出的场景是比较常见的一种,并不是所有的都得这么写, 也有服务端监控写事件,客户端监控读事件,或者全部都监控的场景,这些需要根据业务来分析制作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty 中,实现心跳检测可以使用 IdleStateHandler 类。这个类是一个 ChannelHandler,可以在一段时间内检测 Channel 是否有读或写事件发生,如果超时没有发生事件,就会触发一个 IdleStateEvent 事件。我们可以在 ChannelPipeline 中添加 IdleStateHandler,并在 ChannelInboundHandler 中处理 IdleStateEvent 事件。 以下是一个简单的示例代码: ```java public class HeartbeatServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // 添加 IdleStateHandler,10 秒钟没有读事件,20 秒钟没有写事件,30 秒钟没有读写事件就会触发 IdleStateEvent 事件 pipeline.addLast(new IdleStateHandler(10, 20, 30, TimeUnit.SECONDS)); // 添加自定义的处理器,处理 IdleStateEvent 事件 pipeline.addLast(new HeartbeatServerHandler()); } } public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent e = (IdleStateEvent) evt; if (e.state() == IdleState.READER_IDLE) { // 10 秒钟没有读事件,可以认为客户端已经断开连接 ctx.close(); } else if (e.state() == IdleState.WRITER_IDLE) { // 20 秒钟没有写事件,发送心跳包 ctx.writeAndFlush(new HeartbeatMessage()); } else if (e.state() == IdleState.ALL_IDLE) { // 30 秒钟没有读写事件,可以认为客户端已经断开连接 ctx.close(); } } } } ``` 在上面的代码中,我们首先添加了一个 IdleStateHandler,指定了读超时时间、写超时时间和读写超时时间,然后添加了一个自定义的 ChannelInboundHandlerAdapter,重写了 userEventTriggered 方法,处理 IdleStateEvent 事件。在方法中,我们根据不同的 IdleState 处理不同的事件,例如读超时就关闭连接,写超时就发送心跳包。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值