概述
概述
我们知道在TCP长连接或者WebSocket长连接中一般我们都会使用心跳机制–即发送特殊的数据包来通告对方自己的业务还没有办完,不要关闭链接。那么心跳机制可以用来做什么呢?我们知道网络的传输是不可靠的,当我们发起一个链接请求的过程之中会发生什么事情谁都无法预料,或者断电,服务器重启,断网线之类。如果有这种情况的发生对方也无法判断你是否还在线。所以这时候我们引入心跳机制,在长链接中双方没有数据交互的时候互相发送数据(可能是空包,也可能是特殊数据),对方收到该数据之后也回复相应的数据用以确保双方都在线,这样就可以确保当前链接是有效的。
Netty的心跳机制
我们来看一下Netty的心跳机制的实现,在Netty中提供了IdleStateHandler类来进行心跳的处理,它可以对一个 Channel 的 读/写设置定时器, 当 Channel 在一定事件间隔内没有数据交互时(即处于 idle 状态), 就会触发指定的事件。
public IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
this((long)readerIdleTimeSeconds, (long)writerIdleTimeSeconds, (long)allIdleTimeSeconds, TimeUnit.SECONDS);
- readerIdleTimeSeconds:设置读超时时间;
- writerIdleTimeSeconds:设置写超时时间;
- allIdleTimeSeconds:同时为读或写设置超时时间;
下面我们用代码实例来说明:
服务端
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
// 创建2个线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workGroup = new NioEventLoopGroup();
// 启动程序
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// 往pipeline中加入一个netty提供的IdleStateHandler 提供的处理空闲状态的处理器
// 参数1. long readerIdleTime : 表示多长时间没有读, 就会发送一个心跳检测包检测是否连接
// 参数2. long writerIdleTime : 表示多长时间没有写, 就会发送一个心跳检测包检测是否连接
// 参数 3. long allIdleTime : 表示多长时间没有读写, 就会发送一个心跳检测包检测是否连接
pipeline.addLast(new IdleStateHandler(3,5,7, TimeUnit.SECONDS));
//加入一个对空闲检测进一步处理的handler(自定义)
pipeline.addLast(new NettyServerHandler());
}
});
System.out.println("服务器准备完毕");
ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
服务端事件处理器
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
/**
*
* @param ctx 上下文
* @param evt 事件
* @throws Exception
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if(evt instanceof IdleStateEvent) {
//将 evt 向下转型 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 = "读写空闲";
break;
}
System.out.println(ctx.channel().remoteAddress() + "--超时时间--" + eventType);
System.out.println("服务器做相应处理..");
//如果发生空闲,我们关闭通道
// ctx.channel().close();
}
}
}
如服务端事件处理器
假如一个通道没有在3秒读数据,或者5秒类写数据,发生了读空闲或者写空闲,或者读写空闲,那么就会触发userEventTriggered
方法,并触发相对应的事件,我们可以做出相对于的处理,这就是Netty的心跳机制,
最后
以上就是迷你火为你收集整理的netty学习笔记11 - Netty心跳检测机制的全部内容,希望文章能够帮你解决netty学习笔记11 - Netty心跳检测机制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复