Commit 341e72c0b180611abaa1aec496ca90d4186b27cc

Authored by haohao
1 parent 5ae0224b

feat: 【IoT 物联网】新增简单类型处理器配置和处理器,优化 JSON 解析问题

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/mybatis/config/SimpleTypeHandlerConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.framework.mybatis.config;
  2 +
  3 +import cn.iocoder.yudao.module.iot.framework.mybatis.handler.SimpleObjectTypeHandler;
  4 +import jakarta.annotation.PostConstruct;
  5 +import jakarta.annotation.Resource;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.apache.ibatis.session.SqlSessionFactory;
  8 +import org.apache.ibatis.type.TypeHandlerRegistry;
  9 +import org.springframework.context.annotation.Configuration;
  10 +
  11 +/**
  12 + * 简单类型处理器配置
  13 + * 注册自定义的类型处理器,避免 JSON 解析错误
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Slf4j
  18 +@Configuration
  19 +public class SimpleTypeHandlerConfig {
  20 +
  21 + @Resource
  22 + private SqlSessionFactory sqlSessionFactory;
  23 +
  24 + @PostConstruct
  25 + public void registerTypeHandlers() {
  26 + TypeHandlerRegistry registry = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
  27 +
  28 + // 注册简单的 Object 类型处理器,避免 JSON 解析问题
  29 + registry.register(java.lang.Object.class, new SimpleObjectTypeHandler());
  30 +
  31 + log.info("简单类型处理器注册完成,避免 JSON 解析错误");
  32 + }
  33 +}
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/mybatis/handler/SimpleObjectTypeHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.framework.mybatis.handler;
  2 +
  3 +import org.apache.ibatis.type.BaseTypeHandler;
  4 +import org.apache.ibatis.type.JdbcType;
  5 +
  6 +import java.sql.CallableStatement;
  7 +import java.sql.PreparedStatement;
  8 +import java.sql.ResultSet;
  9 +import java.sql.SQLException;
  10 +
  11 +/**
  12 + * 简单的 Object 类型处理器
  13 + * 直接返回字符串,避免 JSON 解析问题
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +public class SimpleObjectTypeHandler extends BaseTypeHandler<Object> {
  18 +
  19 + @Override
  20 + public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
  21 + throws SQLException {
  22 + ps.setString(i, parameter.toString());
  23 + }
  24 +
  25 + @Override
  26 + public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
  27 + return rs.getString(columnName); // 直接返回字符串
  28 + }
  29 +
  30 + @Override
  31 + public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  32 + return rs.getString(columnIndex); // 直接返回字符串
  33 + }
  34 +
  35 + @Override
  36 + public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  37 + return cs.getString(columnIndex); // 直接返回字符串
  38 + }
  39 +}
0 40 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/device/IotDevicePropertyMapper.xml
... ... @@ -66,8 +66,15 @@
66 66 DESCRIBE product_property_${productId}
67 67 </select>
68 68  
  69 + <resultMap id="IotDevicePropertyRespVOMap"
  70 + type="cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO">
  71 + <result property="value" column="value"
  72 + typeHandler="cn.iocoder.yudao.module.iot.framework.mybatis.handler.SimpleObjectTypeHandler"/>
  73 + <result property="updateTime" column="update_time" javaType="java.lang.Long"/>
  74 + </resultMap>
  75 +
69 76 <select id="selectListByHistory"
70   - resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO">
  77 + resultMap="IotDevicePropertyRespVOMap">
71 78 SELECT ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} AS `value`, ts AS update_time
72 79 FROM device_property_${reqVO.deviceId}
73 80 WHERE ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} IS NOT NULL
... ...
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/router/IotMqttUpstreamHandler.java
... ... @@ -68,7 +68,13 @@ public class IotMqttUpstreamHandler {
68 68  
69 69 log.info("[handle][设备认证成功,建立连接,客户端 ID: {},用户名: {}]", clientId, username);
70 70  
71   - // 2. 设置异常和关闭处理器
  71 + // 2. 设置心跳处理器(监听客户端的 PINGREQ 消息)
  72 + endpoint.pingHandler(v -> {
  73 + log.debug("[handle][收到客户端心跳,客户端 ID: {}]", clientId);
  74 + // Vert.x 会自动发送 PINGRESP 响应,无需手动处理
  75 + });
  76 +
  77 + // 3. 设置异常和关闭处理器
72 78 endpoint.exceptionHandler(ex -> {
73 79 log.warn("[handle][连接异常,客户端 ID: {},地址: {}]", clientId, connectionManager.getEndpointAddress(endpoint));
74 80 cleanupConnection(endpoint);
... ... @@ -77,7 +83,7 @@ public class IotMqttUpstreamHandler {
77 83 cleanupConnection(endpoint);
78 84 });
79 85  
80   - // 3. 设置消息处理器
  86 + // 4. 设置消息处理器
81 87 endpoint.publishHandler(message -> {
82 88 try {
83 89 processMessage(clientId, message.topicName(), message.payload().getBytes());
... ... @@ -100,7 +106,7 @@ public class IotMqttUpstreamHandler {
100 106 }
101 107 });
102 108  
103   - // 4. 设置订阅处理器
  109 + // 5. 设置订阅处理器
104 110 endpoint.subscribeHandler(subscribe -> {
105 111 // 提取主题名称列表用于日志显示
106 112 List<String> topicNames = subscribe.topicSubscriptions().stream()
... ... @@ -115,22 +121,22 @@ public class IotMqttUpstreamHandler {
115 121 endpoint.subscribeAcknowledge(subscribe.messageId(), grantedQoSLevels);
116 122 });
117 123  
118   - // 5. 设置取消订阅处理器
  124 + // 6. 设置取消订阅处理器
119 125 endpoint.unsubscribeHandler(unsubscribe -> {
120 126 log.debug("[handle][设备取消订阅,客户端 ID: {},主题: {}]", clientId, unsubscribe.topics());
121 127 endpoint.unsubscribeAcknowledge(unsubscribe.messageId());
122 128 });
123 129  
124   - // 6. 设置 QoS 2消息的 PUBREL 处理器
  130 + // 7. 设置 QoS 2消息的 PUBREL 处理器
125 131 endpoint.publishReleaseHandler(endpoint::publishComplete);
126 132  
127   - // 7. 设置断开连接处理器
  133 + // 8. 设置断开连接处理器
128 134 endpoint.disconnectHandler(v -> {
129 135 log.debug("[handle][设备断开连接,客户端 ID: {}]", clientId);
130 136 cleanupConnection(endpoint);
131 137 });
132 138  
133   - // 8. 接受连接
  139 + // 9. 接受连接
134 140 endpoint.accept(false);
135 141 }
136 142  
... ...
yudao-module-iot/yudao-module-iot-gateway/src/main/resources/application.yaml
... ... @@ -103,7 +103,6 @@ yudao:
103 103 port: 1883
104 104 max-message-size: 8192
105 105 connect-timeout-seconds: 60
106   - keep-alive-timeout-seconds: 300
107 106 ssl-enabled: false
108 107  
109 108 --- #################### 日志相关配置 ####################
... ...