描述
@Slf4j
public class V1Handler extends AbstractWebSocketHandler {
private static final boolean isDebug = false;
public V1Handler(IBusRemote busRemote) {
this.busRemote = busRemote;
}
private final IBusRemote busRemote;
@Override
public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus status) throws Exception {
super.afterConnectionClosed(session, status);
String clientId = AuthHandler.clientIdSessionIdMap.get(session.getId());
log.info("connection close..." + clientId);
if (clientId != null) {
//远程调用bus下线业务,释放资源
busRemote.onClientCloseOffline(clientId);
//TODO:这里要处理,因为网络变化会导致这里的调用
}
}
}
在本地开发的时候,这里回调是正常的,因为本地的网络稳定,连接稳定。但是上线了以后呢?一旦有网络波动就会触发这个方法。
这是个坑
这个方法在实际生产环境里“非常容易被频繁调用”,而且并不等价于“设备真的下线了”。你现在遇到的情况在 WebSocket + 设备端 场景里非常典型。
可能的原因
TCP 连接被动断开(最常见)
NAT 映射过期(尤其是移动网络 / 家宽)
中间防火墙 / 负载均衡超时
云厂商 LB idle timeout(30s / 60s / 300s)
如何判断有没有下线呢?
那怎么样去判断是否有下线呢?
还是以心跳为准吧,至少我打算这么做。
定时器也不用太频繁,只要5分钟一次就可以,目的是为了释放资源,视具体的业务而定。
我这里即使不释放资源,也不影响使用,如果有信号量占用之类的就要释放了,所以还是以实际情况为准。
这里记录一下这个回调方法的坑。
