diff --git a/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java b/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java index 0d3b89f..039612d 100644 --- a/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java +++ b/viewsh-module-iot/viewsh-module-iot-gateway/src/main/java/com/viewsh/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java @@ -112,17 +112,30 @@ public class IotTcpUpstreamHandler implements Handler { // 2. 获取消息格式类型 String codecType = getMessageCodecType(buffer, socket); + if (codecType == null) { + // 无法识别消息格式,记录警告但不断开连接 + byte[] data = buffer.getBytes(); + String preview = bytesToHex(data, Math.min(32, data.length)); + log.warn("[processMessage][无法识别消息格式,跳过该消息,clientId: {}, 数据前32字节: {}]", + clientId, preview); + return; + } // 3. 解码消息 IotDeviceMessage message; try { message = deviceMessageService.decodeDeviceMessage(buffer.getBytes(), codecType); if (message == null) { - throw new Exception("解码后消息为空"); + // 解码失败(如消息格式错误),记录警告但不断开连接 + log.warn("[processMessage][消息解码失败,跳过该消息,clientId: {}, codecType: {}]", + clientId, codecType); + return; } } catch (Exception e) { - // 消息格式错误时抛出异常,由上层处理连接断开 - throw new Exception("消息解码失败: " + e.getMessage(), e); + // 其他异常也记录警告但不断开连接 + log.warn("[processMessage][消息解码异常,跳过该消息,clientId: {}, codecType: {}, 错误: {}]", + clientId, codecType, e.getMessage()); + return; } // 4. 查找协议处理器 @@ -147,7 +160,7 @@ public class IotTcpUpstreamHandler implements Handler { * 认证结果处理: * - SUCCESS:注册连接,发送上线消息 * - PENDING:等待后续认证步骤(如 JT808 注册后等待鉴权) - * - FAILURE:认证失败,不做处理(协议处理器已发送失败响应) + * - FAILURE:认证失败,如果设备不存在则断开连接,否则只记录日志 * * @param clientId 客户端 ID * @param message 认证消息 @@ -178,9 +191,16 @@ public class IotTcpUpstreamHandler implements Handler { handler.getProtocolType(), result.getMessage()); } else { - // 认证失败:协议处理器已发送失败响应,这里只记录日志 + // 认证失败 + String failureReason = result.getMessage(); log.warn("[handleAuthentication][认证失败,clientId: {}, 协议: {}, 原因: {}]", - clientId, handler.getProtocolType(), result.getMessage()); + clientId, handler.getProtocolType(), failureReason); + + // 如果设备不存在,断开连接 + if (failureReason != null && failureReason.contains("设备不存在")) { + log.warn("[handleAuthentication][设备不存在,断开连接,clientId: {}]", clientId); + socket.close(); + } } } catch (Exception e) { @@ -373,7 +393,7 @@ public class IotTcpUpstreamHandler implements Handler { */ private void cleanupConnection(NetSocket socket) { try { - // 1. 发送离线消息(如果已认证) + // 1. 发送离线消息(如果���认证) IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket); if (connectionInfo != null && connectionInfo.isAuthenticated()) { IotDeviceMessage offlineMessage = IotDeviceMessage.buildStateOffline(); @@ -391,4 +411,26 @@ public class IotTcpUpstreamHandler implements Handler { } } + /** + * 字节数组转十六进制字符串 + * + * @param bytes 字节数组 + * @param limit 最大长度 + * @return 十六进制字符串 + */ + private String bytesToHex(byte[] bytes, int limit) { + if (bytes == null || bytes.length == 0) { + return ""; + } + int length = Math.min(bytes.length, limit); + StringBuilder sb = new StringBuilder(length * 2); + for (int i = 0; i < length; i++) { + sb.append(String.format("%02X", bytes[i])); + } + if (bytes.length > limit) { + sb.append("..."); + } + return sb.toString(); + } + }