最近公司有需求,使用netty服务器来操作设备,这个设备是应答模式,就是上位机发送指令后,下位机会应答(应答才表示指令发送成功),开始的时候我使用的是发送心跳包(心跳包是一个指令,设备会应答)的方式来确定设备是否还在连接中,后来发现电池的电量消耗太快(由于想要省电,当时已经设置为10s一次心跳了,但是还是太快),我们的使用场景是在用户设备使用过程中是不会充电的,所以只能想别的办法,最后找到了一个解决方法。
服务器是在linux环境下,修改/etc/sysctl.conf文件
添加以下内容:
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为5秒钟。
net.ipv4.tcp_keepalive_time = 5
#如果对方不予应答,探测包的发送次数
net.ipv4.tcp_keepalive_probes = 5
#探测消息发送的频率
net.ipv4.tcp_keepalive_intvl = 1
这个是修改的linux tcp发送探测包配置的
修改完成后输入以下命令生效
/sbin/sysctl -p
/sbin/sysctl -w net.ipv4.route.flush=1
这样设置完成以后,每次客户端断开连接后7,8秒后会执行以下方法
public class TcpServerHandler extends SimpleChannelInboundHandler<ByteBuf>{
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throw Exception{
//这里执行客户端断开连接后的操作
}
}
这里的设置不一定适合每一个人,我测试了三个参数都设置为1,这样以后设备断开连接后1,2秒服务器就能感知到,但是也会出现问题,有时候网络不稳定,一个探测包没有探测到,系统就自动断开连接了,所以这个需要自己去进行测试设置为多大最好。
我本身对Linux不是很了解,所以以上说法有错误的地方请指出谢谢。
在想解决方案的时候还想到一种方法,但是不适合我们的场景,也不知道能否实现,这里只是提供一个思路:
设备连接上服务器后,服务器可以记录设备ip,然后ping这个ip来判断设备是否还在连接中,具体操作没有想太多,就到这里吧。