diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/IotMqttProtocol.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/IotMqttProtocol.java index 354cd1b..a1cf47a 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/IotMqttProtocol.java +++ b/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 { deviceMessageService.sendDeviceMessage(offlineMessage, connectionInfo.getProductKey(), connectionInfo.getDeviceName(), serverId); } - - // 2. 注销连接 - connectionManager.unregisterConnection(endpoint); } catch (Exception e) { log.error("[cleanupConnection][清理连接失败,客户端 ID: {},错误: {}]", endpoint.clientIdentifier(), e.getMessage()); + } finally { + // 2. 注销连接,避免发送离线消息失败时残留连接 + connectionManager.unregisterConnection(endpoint); } } diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/manager/IotMqttConnectionManager.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/manager/IotMqttConnectionManager.java index 3d187c8..a9bb277 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/manager/IotMqttConnectionManager.java +++ b/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 { deviceId, getEndpointAddress(oldEndpoint)); // 先清理映射,再关闭连接(避免旧连接处理器干扰) connectionMap.remove(oldEndpoint); - oldEndpoint.close(); + try { + if (oldEndpoint.isConnected()) { + oldEndpoint.close(); + } + } catch (Exception ignored) { + // 连接可能已关闭,忽略异常 + } } // 注册新连接 @@ -107,7 +113,8 @@ public class IotMqttConnectionManager { return; } Long deviceId = connectionInfo.getDeviceId(); - deviceEndpointMap.remove(deviceId); + // 仅当 deviceEndpointMap 中的 endpoint 是当前 endpoint 时才移除,避免误删新连接 + deviceEndpointMap.remove(deviceId, endpoint); log.info("[unregisterConnection][注销设备连接,设备 ID: {},连接: {}]", deviceId, getEndpointAddress(endpoint)); } diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/manager/IotTcpConnectionManager.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/manager/IotTcpConnectionManager.java index 20065f1..9349bed 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/manager/IotTcpConnectionManager.java +++ b/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 { deviceId, oldSocket.remoteAddress()); // 先清理映射,再关闭连接 connectionMap.remove(oldSocket); - oldSocket.close(); + try { + oldSocket.close(); + } catch (Exception ignored) { + // 连接可能已关闭,忽略异常 + } } // 注册新连接 @@ -163,4 +167,4 @@ public class IotTcpConnectionManager { } -} \ No newline at end of file +} diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/manager/IotWebSocketConnectionManager.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/manager/IotWebSocketConnectionManager.java index 92019ff..2dce663 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/manager/IotWebSocketConnectionManager.java +++ b/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 { if (oldSocket != null && oldSocket != socket) { log.info("[registerConnection][设备已有其他连接,断开旧连接,设备 ID: {},旧连接: {}]", deviceId, oldSocket.remoteAddress()); - oldSocket.close(); - // 清理旧连接的映射 + // 先清理映射,再关闭连接 connectionMap.remove(oldSocket); + try { + oldSocket.close(); + } catch (Exception ignored) { + // 连接可能已关闭,忽略异常 + } } // 注册新连接