Commit 73ac8f7ebf170e3f13020170a2a0dca91666f09c
1 parent
43b38dfc
fix(iot): 修复旧连接清理异常导致设备重连失败
Showing
4 changed files
with
24 additions
and
9 deletions
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/IotMqttProtocol.java
| ... | ... | @@ -332,12 +332,12 @@ public class IotMqttProtocol implements IotProtocol { |
| 332 | 332 | deviceMessageService.sendDeviceMessage(offlineMessage, connectionInfo.getProductKey(), |
| 333 | 333 | connectionInfo.getDeviceName(), serverId); |
| 334 | 334 | } |
| 335 | - | |
| 336 | - // 2. 注销连接 | |
| 337 | - connectionManager.unregisterConnection(endpoint); | |
| 338 | 335 | } catch (Exception e) { |
| 339 | 336 | log.error("[cleanupConnection][清理连接失败,客户端 ID: {},错误: {}]", |
| 340 | 337 | endpoint.clientIdentifier(), e.getMessage()); |
| 338 | + } finally { | |
| 339 | + // 2. 注销连接,避免发送离线消息失败时残留连接 | |
| 340 | + connectionManager.unregisterConnection(endpoint); | |
| 341 | 341 | } |
| 342 | 342 | } |
| 343 | 343 | ... | ... |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/manager/IotMqttConnectionManager.java
| ... | ... | @@ -86,7 +86,13 @@ public class IotMqttConnectionManager { |
| 86 | 86 | deviceId, getEndpointAddress(oldEndpoint)); |
| 87 | 87 | // 先清理映射,再关闭连接(避免旧连接处理器干扰) |
| 88 | 88 | connectionMap.remove(oldEndpoint); |
| 89 | - oldEndpoint.close(); | |
| 89 | + try { | |
| 90 | + if (oldEndpoint.isConnected()) { | |
| 91 | + oldEndpoint.close(); | |
| 92 | + } | |
| 93 | + } catch (Exception ignored) { | |
| 94 | + // 连接可能已关闭,忽略异常 | |
| 95 | + } | |
| 90 | 96 | } |
| 91 | 97 | |
| 92 | 98 | // 注册新连接 |
| ... | ... | @@ -107,7 +113,8 @@ public class IotMqttConnectionManager { |
| 107 | 113 | return; |
| 108 | 114 | } |
| 109 | 115 | Long deviceId = connectionInfo.getDeviceId(); |
| 110 | - deviceEndpointMap.remove(deviceId); | |
| 116 | + // 仅当 deviceEndpointMap 中的 endpoint 是当前 endpoint 时才移除,避免误删新连接 | |
| 117 | + deviceEndpointMap.remove(deviceId, endpoint); | |
| 111 | 118 | log.info("[unregisterConnection][注销设备连接,设备 ID: {},连接: {}]", deviceId, getEndpointAddress(endpoint)); |
| 112 | 119 | } |
| 113 | 120 | ... | ... |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/manager/IotTcpConnectionManager.java
| ... | ... | @@ -61,7 +61,11 @@ public class IotTcpConnectionManager { |
| 61 | 61 | deviceId, oldSocket.remoteAddress()); |
| 62 | 62 | // 先清理映射,再关闭连接 |
| 63 | 63 | connectionMap.remove(oldSocket); |
| 64 | - oldSocket.close(); | |
| 64 | + try { | |
| 65 | + oldSocket.close(); | |
| 66 | + } catch (Exception ignored) { | |
| 67 | + // 连接可能已关闭,忽略异常 | |
| 68 | + } | |
| 65 | 69 | } |
| 66 | 70 | |
| 67 | 71 | // 注册新连接 |
| ... | ... | @@ -163,4 +167,4 @@ public class IotTcpConnectionManager { |
| 163 | 167 | |
| 164 | 168 | } |
| 165 | 169 | |
| 166 | -} | |
| 167 | 170 | \ No newline at end of file |
| 171 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/manager/IotWebSocketConnectionManager.java
| ... | ... | @@ -46,9 +46,13 @@ public class IotWebSocketConnectionManager { |
| 46 | 46 | if (oldSocket != null && oldSocket != socket) { |
| 47 | 47 | log.info("[registerConnection][设备已有其他连接,断开旧连接,设备 ID: {},旧连接: {}]", |
| 48 | 48 | deviceId, oldSocket.remoteAddress()); |
| 49 | - oldSocket.close(); | |
| 50 | - // 清理旧连接的映射 | |
| 49 | + // 先清理映射,再关闭连接 | |
| 51 | 50 | connectionMap.remove(oldSocket); |
| 51 | + try { | |
| 52 | + oldSocket.close(); | |
| 53 | + } catch (Exception ignored) { | |
| 54 | + // 连接可能已关闭,忽略异常 | |
| 55 | + } | |
| 52 | 56 | } |
| 53 | 57 | |
| 54 | 58 | // 注册新连接 | ... | ... |