困扰了我一周的问题,终于解决了,而且是睡醒一觉,突然就顿悟了。问题:每次设备登录,都会和netty建立一个常连接,如果不能判断是否为同一个常连接,常连接就会断掉。emo,能懂我的意思吧?
- 在通讯初始化的时候,就定义一个全局变量,并给这个全局变量写一个查询、清空、更新方法。
//全局变量
Map<String, ChannelHandlerContext> contextHashMap = new HashMap<>();
//获取全局变量信息
public ChannelHandlerContext getContext(String key){
return contextHashMap.get(key);
}
//更新全局变量信息
public void addContext(String key,ChannelHandlerContext ctx){
contextHashMap.put(key,ctx);
}
//清空全局变量信息
public void deleteContext(String key){
contextHashMap.remove(key);
}
- 设备在第一次和程序建立通讯的时候,全局变量是没有值的。在注册或者注册成功的代码后,把常连接赋值给全局变量,心跳时间之内,设备再一次建立通讯,直接把第一次的常连接关闭,再把全部变量再更新一次。
//如果判断不是空,就代表已经注册过了。
if(Optional.ofNullable(usrChannelHandlerImpl.getContext(usrDtuMsg.getIdentityId())).isPresent()){
ChannelHandlerContext channelHandlerContext = usrChannelHandlerImpl.getContext(usrDtuMsg.getIdentityId());
//如果两个常连接的IP和端口号不一致,就直接关闭上一个常连接
if(!channelHandlerContext.channel().remoteAddress().equals(ctx.channel().remoteAddress())){
channelHandlerContext.close();
}
}
//每次都更新一次。
usrChannelHandlerImpl.addContext(usrDtuMsg.getIdentityId(),ctx);
- 心跳那里,每断开一次心跳,都清空一下全局变量。
//每次心跳离线,都清除一下常连接信息
usrChannelHandlerImpl.deleteContext(conn.getIdentityId());