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 168e959..39656e1 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 @@ -139,13 +139,50 @@ public class IotTcpUpstreamHandler implements Handler { return; } - // 5. 判断是否为认证消息 - if (isAuthenticationMessage(message)) { - handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler); - } else { - handleBusinessWithProtocol(clientId, message, codecType, socket, handler); - } - } + // 5. 判断是否为认证消息 + if (isAuthenticationMessage(message)) { + handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler); + } else { + // 针对 JT808 协议的特殊处理:如果是位置上报(thing.property.post)且包含身份信息(手机号),尝试自动注册 + // 这可以解决设备重启后未注册就发送数据的问题,或者简化认证流程 + if (CODEC_TYPE_JT808.equals(codecType)) { + tryAutoRegisterJt808(clientId, message, codecType, socket, handler); + } else { + handleBusinessWithProtocol(clientId, message, codecType, socket, handler); + } + } + } + + /** + * 尝试自动注册 JT808 设备 + *

+ * JT808 协议中,消息头包含终端手机号。如果设备未认证但发送了有效数据, + * 我们可以尝试提取手机号并进行隐式认证,而不是直接断开连接。 + */ + private void tryAutoRegisterJt808(String clientId, IotDeviceMessage message, + String codecType, NetSocket socket, + ProtocolHandler handler) { + // 如果已认证,直接处理业务 + if (!connectionManager.isNotAuthenticated(socket)) { + handleBusinessWithProtocol(clientId, message, codecType, socket, handler); + return; + } + + log.info("[tryAutoRegisterJt808][尝试自动认证 JT808 设备,clientId: {}]", clientId); + + // 使用认证逻辑处理(JT808 协议处理器会提取手机号进行认证) + // 这里把业务消息当作认证消息处理,如果协议处理器支持从业务消息提取身份,就能成功 + // 注意:这依赖于 Jt808ProtocolHandler 的 handleAuthentication 实现能够处理非注册消息 + handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler); + + // 如果认证成功(handleAuthenticationWithProtocol 内部会注册连接),则继续处理业务消息 + if (!connectionManager.isNotAuthenticated(socket)) { + log.info("[tryAutoRegisterJt808][自动认证成功,继续处理业务消息,clientId: {}]", clientId); + handleBusinessWithProtocol(clientId, message, codecType, socket, handler); + } else { + // 认证依然失败,提示未认证(日志已在 handleAuthenticationWithProtocol 中打印) + } + } /** * 使用协议处理器处理认证消息