Commit b0949c085116819fa76523580ca100f7ebb40692

Authored by haohao
1 parent 65cd56bc

feat:【IoT 物联网】优化 TCP JSON 编解码器和认证参数解析逻辑

yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java
... ... @@ -9,6 +9,8 @@ import lombok.Data;
9 9 import lombok.NoArgsConstructor;
10 10 import org.springframework.stereotype.Component;
11 11  
  12 +import java.nio.charset.StandardCharsets;
  13 +
12 14 /**
13 15 * TCP JSON 格式 {@link IotDeviceMessage} 编解码器
14 16 *
... ... @@ -93,7 +95,8 @@ public class IotTcpJsonDeviceMessageCodec implements IotDeviceMessageCodec {
93 95 @Override
94 96 @SuppressWarnings("DataFlowIssue")
95 97 public IotDeviceMessage decode(byte[] bytes) {
96   - TcpJsonMessage tcpJsonMessage = JsonUtils.parseObject(bytes, TcpJsonMessage.class);
  98 + String jsonStr = new String(bytes, StandardCharsets.UTF_8).trim();
  99 + TcpJsonMessage tcpJsonMessage = JsonUtils.parseObject(jsonStr, TcpJsonMessage.class);
97 100 Assert.notNull(tcpJsonMessage, "消息不能为空");
98 101 Assert.notBlank(tcpJsonMessage.getMethod(), "消息方法不能为空");
99 102 return IotDeviceMessage.of(
... ...
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java
... ... @@ -124,7 +124,14 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
124 124 handleBusinessRequest(clientId, message, codecType, socket);
125 125 }
126 126 } catch (Exception e) {
127   - log.error("[processMessage][处理消息失败,客户端 ID: {}]", clientId, e);
  127 + log.error("[processMessage][处理消息失败,客户端 ID: {},消息方法: {}]",
  128 + clientId, message.getMethod(), e);
  129 + // 发送错误响应,避免客户端一直等待
  130 + try {
  131 + sendErrorResponse(socket, message.getRequestId(), "消息处理失败", codecType);
  132 + } catch (Exception responseEx) {
  133 + log.error("[processMessage][发送错误响应失败,客户端 ID: {}]", clientId, responseEx);
  134 + }
128 135 }
129 136 }
130 137  
... ... @@ -140,9 +147,9 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
140 147 NetSocket socket) {
141 148 try {
142 149 // 1.1 解析认证参数
143   - IotDeviceAuthReqDTO authParams = JsonUtils.parseObject(message.getParams().toString(),
144   - IotDeviceAuthReqDTO.class);
  150 + IotDeviceAuthReqDTO authParams = parseAuthParams(message.getParams());
145 151 if (authParams == null) {
  152 + log.warn("[handleAuthenticationRequest][认证参数解析失败,客户端 ID: {}]", clientId);
146 153 sendErrorResponse(socket, message.getRequestId(), "认证参数不完整", codecType);
147 154 return;
148 155 }
... ... @@ -205,6 +212,8 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
205 212 // 3. 发送消息到消息总线
206 213 deviceMessageService.sendDeviceMessage(message, connectionInfo.getProductKey(),
207 214 connectionInfo.getDeviceName(), serverId);
  215 + log.info("[handleBusinessRequest][发送消息到消息总线,客户端 ID: {},消息: {}",
  216 + clientId, message.toString());
208 217 } catch (Exception e) {
209 218 log.error("[handleBusinessRequest][业务请求处理异常,客户端 ID: {}]", clientId, e);
210 219 }
... ... @@ -359,4 +368,41 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
359 368 sendResponse(socket, true, message, requestId, codecType);
360 369 }
361 370  
  371 + /**
  372 + * 解析认证参数
  373 + *
  374 + * @param params 参数对象(通常为 Map 类型)
  375 + * @return 认证参数 DTO,解析失败时返回 null
  376 + */
  377 + private IotDeviceAuthReqDTO parseAuthParams(Object params) {
  378 + if (params == null) {
  379 + return null;
  380 + }
  381 +
  382 + try {
  383 + // 参数默认为 Map 类型,直接转换
  384 + if (params instanceof java.util.Map) {
  385 + @SuppressWarnings("unchecked")
  386 + java.util.Map<String, Object> paramMap = (java.util.Map<String, Object>) params;
  387 + return new IotDeviceAuthReqDTO()
  388 + .setClientId(MapUtil.getStr(paramMap, "clientId"))
  389 + .setUsername(MapUtil.getStr(paramMap, "username"))
  390 + .setPassword(MapUtil.getStr(paramMap, "password"));
  391 + }
  392 +
  393 + // 如果已经是目标类型,直接返回
  394 + if (params instanceof IotDeviceAuthReqDTO) {
  395 + return (IotDeviceAuthReqDTO) params;
  396 + }
  397 +
  398 + // 其他情况尝试 JSON 转换
  399 + String jsonStr = JsonUtils.toJsonString(params);
  400 + return JsonUtils.parseObject(jsonStr, IotDeviceAuthReqDTO.class);
  401 +
  402 + } catch (Exception e) {
  403 + log.error("[parseAuthParams][解析认证参数失败]", e);
  404 + return null;
  405 + }
  406 + }
  407 +
362 408 }
363 409 \ No newline at end of file
... ...