netty怎样知道连接活性,长时间打断点时连接一直没有断开,杀进程连接立马断开?
由于最近在做硬件通讯交互方面的项目,使用的是 Netty 作为中间件,存在以下两个应用场景:
1)业务平台通过 Netty 下发一条指令到终端设备,且终端设备需要上行指令确认,说明该终端设备收到该条指令。但是,存在网络抖动或终端设备突然失联等情况,此时,客户端并未收到该条指令。因此,期望服务端能够在指定时间间隔和重试次数的情况下重发未收到上行确认的指令。
2)周期性下发通讯指令,获得终端设备的近实时数据,如定位信息、终端状态等。
根据参考资料,没有直接回答如何检测连接的活性并确保在杀进程时连接立即断开的方法。但是可以根据Netty框架的特点和提供的API来解决该问题。
public class HeartbeatHandler extends ChannelDuplexHandler {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state() == IdleState.READER_IDLE) {
// 读超时,断开连接
ctx.close();
} else if (event.state() == IdleState.WRITER_IDLE) {
// 写超时,发送心跳消息
ctx.writeAndFlush("heartbeat");
}
} else {
super.userEventTriggered(ctx, evt);
}
}
}
在创建ChannelPipeline时,添加该Handler,并设置读、写超时时间:
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS))
.addLast(new HeartbeatHandler())
.addLast(new NettyClientHandler());
上述代码中,设置了读超时时间为30秒,写超时时间为0,即不处理写超时。在HeartbeatHandler中可以根据读、写超时来分别处理。
public class NettyClient {
private Channel channel;
// ...
public void connect(String hostname,int port) {
// ...
this.channel = future.channel();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (channel != null) {
channel.close();
}
group.shutdownGracefully();
}));
}
}
在connect方法中,将获取到的Channel实例赋值给成员变量channel,在钩子函数中关闭该连接。这样,当程序被强制杀死时,钩子函数会被调用,从而可以主动关闭连接。如果不加入钩子函数,在程序被强制杀死时,连接可能会处于半开状态,难以断开。
建立心跳