Commit 4cefea68809b5ca38903c6254357ac985b974810
1 parent
4746281d
【功能完善】IoT: 添加 MQTT 消息处理器,重构设备属性和事件上报逻辑,优化消息处理流程
Showing
5 changed files
with
212 additions
and
141 deletions
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/downstream/router/IotDevicePropertySetVertxHandler.java
| ... | ... | @@ -16,7 +16,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC |
| 16 | 16 | import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR; |
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | - * IoT 设备服务设置 Vertx Handler | |
| 19 | + * IoT 设置设备属性 Vertx Handler | |
| 20 | 20 | * |
| 21 | 21 | * 芋道源码 |
| 22 | 22 | */ | ... | ... |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/config/IotPluginEmqxAutoConfiguration.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.plugin.emqx.config; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 4 | -import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties; | |
| 5 | 4 | import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamHandler; |
| 6 | -import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer; | |
| 7 | 5 | import cn.iocoder.yudao.module.iot.plugin.emqx.downstream.IotDeviceDownstreamHandlerImpl; |
| 8 | 6 | import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.IotDeviceUpstreamServer; |
| 9 | 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| ... | ... | @@ -21,10 +19,8 @@ public class IotPluginEmqxAutoConfiguration { |
| 21 | 19 | |
| 22 | 20 | @Bean(initMethod = "start", destroyMethod = "stop") |
| 23 | 21 | public IotDeviceUpstreamServer deviceUpstreamServer(IotDeviceUpstreamApi deviceUpstreamApi, |
| 24 | - IotPluginCommonProperties commonProperties, | |
| 25 | - IotPluginEmqxProperties emqxProperties, | |
| 26 | - IotDeviceDownstreamServer deviceDownstreamServer) { | |
| 27 | - return new IotDeviceUpstreamServer(commonProperties, emqxProperties, deviceUpstreamApi, deviceDownstreamServer); | |
| 22 | + IotPluginEmqxProperties emqxProperties) { | |
| 23 | + return new IotDeviceUpstreamServer(emqxProperties, deviceUpstreamApi); | |
| 28 | 24 | } |
| 29 | 25 | |
| 30 | 26 | @Bean | ... | ... |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/downstream/IotDeviceDownstreamHandlerImpl.java
| ... | ... | @@ -14,6 +14,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle |
| 14 | 14 | |
| 15 | 15 | @Override |
| 16 | 16 | public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) { |
| 17 | + // 设备服务调用 | |
| 18 | + // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier} | |
| 19 | + // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/${tsl.service.identifier}_reply | |
| 17 | 20 | return CommonResult.success(true); |
| 18 | 21 | } |
| 19 | 22 | |
| ... | ... | @@ -24,6 +27,9 @@ public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandle |
| 24 | 27 | |
| 25 | 28 | @Override |
| 26 | 29 | public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) { |
| 30 | + // 设置设备属性 标准 JSON | |
| 31 | + // 请求Topic:/sys/${productKey}/${deviceName}/thing/service/property/set | |
| 32 | + // 响应Topic:/sys/${productKey}/${deviceName}/thing/service/property/set_reply | |
| 27 | 33 | return CommonResult.success(true); |
| 28 | 34 | } |
| 29 | 35 | ... | ... |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/IotDeviceUpstreamServer.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.plugin.emqx.upstream; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.IdUtil; |
| 4 | -import cn.hutool.json.JSONObject; | |
| 5 | -import cn.hutool.json.JSONUtil; | |
| 6 | 4 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 7 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO; | |
| 8 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO; | |
| 9 | -import cn.iocoder.yudao.module.iot.plugin.common.config.IotPluginCommonProperties; | |
| 10 | -import cn.iocoder.yudao.module.iot.plugin.common.downstream.IotDeviceDownstreamServer; | |
| 11 | -import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils; | |
| 12 | 5 | import cn.iocoder.yudao.module.iot.plugin.emqx.config.IotPluginEmqxProperties; |
| 13 | 6 | import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router.IotDeviceAuthVertxHandler; |
| 7 | +import cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router.IotDeviceMqttMessageHandler; | |
| 8 | +import io.netty.handler.codec.mqtt.MqttQoS; | |
| 14 | 9 | import io.vertx.core.Vertx; |
| 15 | 10 | import io.vertx.core.http.HttpServer; |
| 16 | 11 | import io.vertx.ext.web.Router; |
| ... | ... | @@ -19,47 +14,28 @@ import io.vertx.mqtt.MqttClient; |
| 19 | 14 | import io.vertx.mqtt.MqttClientOptions; |
| 20 | 15 | import lombok.extern.slf4j.Slf4j; |
| 21 | 16 | |
| 22 | -import java.time.LocalDateTime; | |
| 23 | - | |
| 24 | 17 | /** |
| 25 | 18 | * IoT 设备下行服务端,接收来自 device 设备的请求,转发给 server 服务器 |
| 26 | 19 | * <p> |
| 27 | 20 | * 协议:HTTP、MQTT |
| 28 | - * 参考:<a href= | |
| 29 | - * "https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.97a72915vRck44#section-g4j-5zg-12b">...</a> | |
| 30 | 21 | * |
| 31 | 22 | * @author haohao |
| 32 | 23 | */ |
| 33 | 24 | @Slf4j |
| 34 | 25 | public class IotDeviceUpstreamServer { |
| 35 | 26 | |
| 36 | - // 设备上报属性 标准 JSON | |
| 37 | - // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post | |
| 38 | - // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply | |
| 39 | - // 设备上报事件 标准 JSON | |
| 40 | - // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post | |
| 41 | - // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply | |
| 42 | - | |
| 43 | - private static final String SYS_TOPIC_PREFIX = "/sys/"; | |
| 44 | - private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post"; | |
| 45 | - private static final String EVENT_POST_TOPIC_PREFIX = "/thing/event/"; | |
| 46 | - private static final String EVENT_POST_TOPIC_SUFFIX = "/post"; | |
| 47 | - | |
| 48 | 27 | private static final int RECONNECT_DELAY = 5000; // 重连延迟时间(毫秒) |
| 49 | - private static final int QOS_LEVEL = 1; | |
| 50 | 28 | |
| 51 | 29 | private final Vertx vertx; |
| 52 | 30 | private final HttpServer server; |
| 53 | 31 | private final MqttClient client; |
| 54 | 32 | private final IotPluginEmqxProperties emqxProperties; |
| 55 | - private final IotDeviceUpstreamApi deviceUpstreamApi; | |
| 33 | + private final IotDeviceMqttMessageHandler mqttMessageHandler; | |
| 56 | 34 | |
| 57 | - public IotDeviceUpstreamServer(IotPluginCommonProperties commonProperties, | |
| 58 | - IotPluginEmqxProperties emqxProperties, | |
| 59 | - IotDeviceUpstreamApi deviceUpstreamApi, | |
| 60 | - IotDeviceDownstreamServer deviceDownstreamServer) { | |
| 35 | + public IotDeviceUpstreamServer(IotPluginEmqxProperties emqxProperties, | |
| 36 | + IotDeviceUpstreamApi deviceUpstreamApi) { | |
| 61 | 37 | this.emqxProperties = emqxProperties; |
| 62 | - this.deviceUpstreamApi = deviceUpstreamApi; | |
| 38 | + | |
| 63 | 39 | // 创建 Vertx 实例 |
| 64 | 40 | this.vertx = Vertx.vertx(); |
| 65 | 41 | // 创建 Router 实例 |
| ... | ... | @@ -77,6 +53,7 @@ public class IotDeviceUpstreamServer { |
| 77 | 53 | .setPassword(emqxProperties.getMqttPassword()) |
| 78 | 54 | .setSsl(emqxProperties.isMqttSsl()); |
| 79 | 55 | client = MqttClient.create(vertx, options); |
| 56 | + this.mqttMessageHandler = new IotDeviceMqttMessageHandler(deviceUpstreamApi, client); | |
| 80 | 57 | } |
| 81 | 58 | |
| 82 | 59 | /** |
| ... | ... | @@ -108,109 +85,7 @@ public class IotDeviceUpstreamServer { |
| 108 | 85 | * 设置 MQTT 消息处理器 |
| 109 | 86 | */ |
| 110 | 87 | private void setupMessageHandler() { |
| 111 | - client.publishHandler(message -> { | |
| 112 | - String topic = message.topicName(); | |
| 113 | - String payload = message.payload().toString(); | |
| 114 | - log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload); | |
| 115 | - | |
| 116 | - try { | |
| 117 | - handleMessage(topic, payload); | |
| 118 | - } catch (Exception e) { | |
| 119 | - log.error("[messageHandler][处理消息失败][topic: {}][payload: {}]", topic, payload, e); | |
| 120 | - } | |
| 121 | - }); | |
| 122 | - } | |
| 123 | - | |
| 124 | - /** | |
| 125 | - * 处理 MQTT 消息 | |
| 126 | - */ | |
| 127 | - private void handleMessage(String topic, String payload) { | |
| 128 | - // 校验前缀 | |
| 129 | - if (!topic.startsWith(SYS_TOPIC_PREFIX)) { | |
| 130 | - log.warn("[handleMessage][未知的消息类型][topic: {}]", topic); | |
| 131 | - return; | |
| 132 | - } | |
| 133 | - | |
| 134 | - // 处理设备属性上报消息 | |
| 135 | - if (topic.endsWith(PROPERTY_POST_TOPIC)) { | |
| 136 | - log.info("[handleMessage][接收到设备属性上报][topic: {}]", topic); | |
| 137 | - handlePropertyPost(topic, payload); | |
| 138 | - return; | |
| 139 | - } | |
| 140 | - | |
| 141 | - // 处理设备事件上报消息 | |
| 142 | - if (topic.contains(EVENT_POST_TOPIC_PREFIX) && topic.endsWith(EVENT_POST_TOPIC_SUFFIX)) { | |
| 143 | - log.info("[handleMessage][接收到设备事件上报][topic: {}]", topic); | |
| 144 | - handleEventPost(topic, payload); | |
| 145 | - return; | |
| 146 | - } | |
| 147 | - | |
| 148 | - // 未知消息类型 | |
| 149 | - log.warn("[handleMessage][未知的消息类型][topic: {}]", topic); | |
| 150 | - } | |
| 151 | - | |
| 152 | - /** | |
| 153 | - * 处理设备属性上报 | |
| 154 | - */ | |
| 155 | - private void handlePropertyPost(String topic, String payload) { | |
| 156 | - // /sys/${productKey}/${deviceName}/thing/event/property/post | |
| 157 | - // 解析消息内容 | |
| 158 | - JSONObject jsonObject = JSONUtil.parseObj(payload); | |
| 159 | - String[] topicParts = topic.split("/"); | |
| 160 | - | |
| 161 | - // 构建设备属性上报请求对象 | |
| 162 | - IotDevicePropertyReportReqDTO reportReqDTO = buildPropertyReportDTO(jsonObject, topicParts); | |
| 163 | - | |
| 164 | - // 调用上游 API 处理设备上报数据 | |
| 165 | - deviceUpstreamApi.reportDeviceProperty(reportReqDTO); | |
| 166 | - log.info("[handlePropertyPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]", | |
| 167 | - topic, JSONUtil.toJsonStr(reportReqDTO)); | |
| 168 | - } | |
| 169 | - | |
| 170 | - /** | |
| 171 | - * 处理设备事件上报 | |
| 172 | - */ | |
| 173 | - private void handleEventPost(String topic, String payload) { | |
| 174 | - // /sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post | |
| 175 | - // 解析消息内容 | |
| 176 | - JSONObject jsonObject = JSONUtil.parseObj(payload); | |
| 177 | - String[] topicParts = topic.split("/"); | |
| 178 | - | |
| 179 | - // 构建设备事件上报请求对象 | |
| 180 | - IotDeviceEventReportReqDTO reportReqDTO = buildEventReportDTO(jsonObject, topicParts); | |
| 181 | - | |
| 182 | - // 调用上游 API 处理设备上报数据 | |
| 183 | - deviceUpstreamApi.reportDeviceEvent(reportReqDTO); | |
| 184 | - log.info("[handleEventPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]", | |
| 185 | - topic, JSONUtil.toJsonStr(reportReqDTO)); | |
| 186 | - } | |
| 187 | - | |
| 188 | - /** | |
| 189 | - * 构建设备属性上报请求对象 | |
| 190 | - */ | |
| 191 | - private IotDevicePropertyReportReqDTO buildPropertyReportDTO(JSONObject jsonObject, | |
| 192 | - String[] topicParts) { | |
| 193 | - return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO() | |
| 194 | - .setRequestId(jsonObject.getStr("id")) | |
| 195 | - .setProcessId(IotPluginCommonUtils.getProcessId()) | |
| 196 | - .setReportTime(LocalDateTime.now()) | |
| 197 | - .setProductKey(topicParts[2]) | |
| 198 | - .setDeviceName(topicParts[3])) | |
| 199 | - .setProperties(jsonObject.getJSONObject("params")); | |
| 200 | - } | |
| 201 | - | |
| 202 | - /** | |
| 203 | - * 构建设备事件上报请求对象 | |
| 204 | - */ | |
| 205 | - private IotDeviceEventReportReqDTO buildEventReportDTO(JSONObject jsonObject, String[] topicParts) { | |
| 206 | - return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO() | |
| 207 | - .setRequestId(jsonObject.getStr("id")) | |
| 208 | - .setProcessId(IotPluginCommonUtils.getProcessId()) | |
| 209 | - .setReportTime(LocalDateTime.now()) | |
| 210 | - .setProductKey(topicParts[2]) | |
| 211 | - .setDeviceName(topicParts[3])) | |
| 212 | - .setIdentifier(topicParts[4]) | |
| 213 | - .setParams(jsonObject.getJSONObject("params")); | |
| 88 | + client.publishHandler(mqttMessageHandler::handle); | |
| 214 | 89 | } |
| 215 | 90 | |
| 216 | 91 | /** |
| ... | ... | @@ -244,7 +119,7 @@ public class IotDeviceUpstreamServer { |
| 244 | 119 | private void subscribeToTopics() { |
| 245 | 120 | String[] topics = emqxProperties.getMqttTopics().split(","); |
| 246 | 121 | for (String topic : topics) { |
| 247 | - client.subscribe(topic, QOS_LEVEL) | |
| 122 | + client.subscribe(topic, MqttQoS.AT_LEAST_ONCE.value()) | |
| 248 | 123 | .onSuccess(v -> log.info("[subscribeToTopics][成功订阅主题: {}]", topic)) |
| 249 | 124 | .onFailure(err -> log.error("[subscribeToTopics][订阅主题失败: {}]", topic, err)); |
| 250 | 125 | } | ... | ... |
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-emqx/src/main/java/cn/iocoder/yudao/module/iot/plugin/emqx/upstream/router/IotDeviceMqttMessageHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.plugin.emqx.upstream.router; | |
| 2 | + | |
| 3 | +import cn.hutool.json.JSONObject; | |
| 4 | +import cn.hutool.json.JSONUtil; | |
| 5 | +import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; | |
| 6 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO; | |
| 7 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO; | |
| 8 | +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils; | |
| 9 | +import io.netty.handler.codec.mqtt.MqttQoS; | |
| 10 | +import io.vertx.core.buffer.Buffer; | |
| 11 | +import io.vertx.mqtt.MqttClient; | |
| 12 | +import io.vertx.mqtt.messages.MqttPublishMessage; | |
| 13 | +import lombok.extern.slf4j.Slf4j; | |
| 14 | + | |
| 15 | +import java.time.LocalDateTime; | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * IoT 设备 MQTT 消息处理器 | |
| 19 | + * <p> | |
| 20 | + * 参考: | |
| 21 | + * <p> | |
| 22 | + * "<a href="https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services?spm=a2c4g.11186623.0.0.97a72915vRck44#section-g4j-5zg-12b">...</a>"> | |
| 23 | + */ | |
| 24 | +@Slf4j | |
| 25 | +public class IotDeviceMqttMessageHandler { | |
| 26 | + | |
| 27 | + // 设备上报属性 标准 JSON | |
| 28 | + // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/property/post | |
| 29 | + // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/property/post_reply | |
| 30 | + // 设备上报事件 标准 JSON | |
| 31 | + // 请求Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post | |
| 32 | + // 响应Topic:/sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply | |
| 33 | + | |
| 34 | + private static final String SYS_TOPIC_PREFIX = "/sys/"; | |
| 35 | + private static final String PROPERTY_POST_TOPIC = "/thing/event/property/post"; | |
| 36 | + private static final String EVENT_POST_TOPIC_PREFIX = "/thing/event/"; | |
| 37 | + private static final String EVENT_POST_TOPIC_SUFFIX = "/post"; | |
| 38 | + | |
| 39 | + private final IotDeviceUpstreamApi deviceUpstreamApi; | |
| 40 | + private final MqttClient mqttClient; | |
| 41 | + | |
| 42 | + public IotDeviceMqttMessageHandler(IotDeviceUpstreamApi deviceUpstreamApi, MqttClient mqttClient) { | |
| 43 | + this.deviceUpstreamApi = deviceUpstreamApi; | |
| 44 | + this.mqttClient = mqttClient; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public void handle(MqttPublishMessage message) { | |
| 48 | + String topic = message.topicName(); | |
| 49 | + String payload = message.payload().toString(); | |
| 50 | + log.info("[messageHandler][接收到消息][topic: {}][payload: {}]", topic, payload); | |
| 51 | + | |
| 52 | + try { | |
| 53 | + handleMessage(topic, payload); | |
| 54 | + } catch (Exception e) { | |
| 55 | + log.error("[messageHandler][处理消息失败][topic: {}][payload: {}]", topic, payload, e); | |
| 56 | + } | |
| 57 | + } | |
| 58 | + | |
| 59 | + private void handleMessage(String topic, String payload) { | |
| 60 | + // 校验前缀 | |
| 61 | + if (!topic.startsWith(SYS_TOPIC_PREFIX)) { | |
| 62 | + log.warn("[handleMessage][未知的消息类型][topic: {}]", topic); | |
| 63 | + return; | |
| 64 | + } | |
| 65 | + | |
| 66 | + // 处理设备属性上报消息 | |
| 67 | + if (topic.endsWith(PROPERTY_POST_TOPIC)) { | |
| 68 | + log.info("[handleMessage][接收到设备属性上报][topic: {}]", topic); | |
| 69 | + handlePropertyPost(topic, payload); | |
| 70 | + return; | |
| 71 | + } | |
| 72 | + | |
| 73 | + // 处理设备事件上报消息 | |
| 74 | + if (topic.contains(EVENT_POST_TOPIC_PREFIX) && topic.endsWith(EVENT_POST_TOPIC_SUFFIX)) { | |
| 75 | + log.info("[handleMessage][接收到设备事件上报][topic: {}]", topic); | |
| 76 | + handleEventPost(topic, payload); | |
| 77 | + return; | |
| 78 | + } | |
| 79 | + | |
| 80 | + // 未知消息类型 | |
| 81 | + log.warn("[handleMessage][未知的消息类型][topic: {}]", topic); | |
| 82 | + } | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * 处理设备属性上报消息 | |
| 86 | + * | |
| 87 | + * @param topic 主题 | |
| 88 | + * @param payload 消息内容 | |
| 89 | + */ | |
| 90 | + private void handlePropertyPost(String topic, String payload) { | |
| 91 | + // 解析消息内容 | |
| 92 | + JSONObject jsonObject = JSONUtil.parseObj(payload); | |
| 93 | + String[] topicParts = topic.split("/"); | |
| 94 | + | |
| 95 | + // 构建设备属性上报请求对象 | |
| 96 | + IotDevicePropertyReportReqDTO reportReqDTO = buildPropertyReportDTO(jsonObject, topicParts); | |
| 97 | + | |
| 98 | + // 调用上游 API 处理设备上报数据 | |
| 99 | + deviceUpstreamApi.reportDeviceProperty(reportReqDTO); | |
| 100 | + log.info("[handlePropertyPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]", | |
| 101 | + topic, JSONUtil.toJsonStr(reportReqDTO)); | |
| 102 | + | |
| 103 | + // 发送响应消息 | |
| 104 | + String replyTopic = topic + "_reply"; | |
| 105 | + JSONObject response = new JSONObject() | |
| 106 | + .set("id", jsonObject.getStr("id")) | |
| 107 | + .set("code", 200) | |
| 108 | + .set("data", new JSONObject()) | |
| 109 | + .set("message", "success") | |
| 110 | + .set("method", "thing.event.property.post"); | |
| 111 | + | |
| 112 | + mqttClient.publish(replyTopic, | |
| 113 | + Buffer.buffer(response.toString()), | |
| 114 | + MqttQoS.AT_LEAST_ONCE, | |
| 115 | + false, | |
| 116 | + false); | |
| 117 | + log.info("[handlePropertyPost][发送响应消息成功][topic: {}][response: {}]", | |
| 118 | + replyTopic, response.toString()); | |
| 119 | + } | |
| 120 | + | |
| 121 | + /** | |
| 122 | + * 处理设备事件上报消息 | |
| 123 | + * | |
| 124 | + * @param topic 主题 | |
| 125 | + * @param payload 消息内容 | |
| 126 | + */ | |
| 127 | + private void handleEventPost(String topic, String payload) { | |
| 128 | + // 解析消息内容 | |
| 129 | + JSONObject jsonObject = JSONUtil.parseObj(payload); | |
| 130 | + String[] topicParts = topic.split("/"); | |
| 131 | + | |
| 132 | + // 构建设备事件上报请求对象 | |
| 133 | + IotDeviceEventReportReqDTO reportReqDTO = buildEventReportDTO(jsonObject, topicParts); | |
| 134 | + | |
| 135 | + // 调用上游 API 处理设备上报数据 | |
| 136 | + deviceUpstreamApi.reportDeviceEvent(reportReqDTO); | |
| 137 | + log.info("[handleEventPost][处理设备上行消息成功][topic: {}][reportReqDTO: {}]", | |
| 138 | + topic, JSONUtil.toJsonStr(reportReqDTO)); | |
| 139 | + | |
| 140 | + // 发送响应消息 | |
| 141 | + String replyTopic = topic + "_reply"; | |
| 142 | + String eventIdentifier = topicParts[6]; // 从 topic 中获取事件标识符 | |
| 143 | + JSONObject response = new JSONObject() | |
| 144 | + .set("id", jsonObject.getStr("id")) | |
| 145 | + .set("code", 200) | |
| 146 | + .set("data", new JSONObject()) | |
| 147 | + .set("message", "success") | |
| 148 | + .set("method", "thing.event." + eventIdentifier + ".post"); | |
| 149 | + | |
| 150 | + mqttClient.publish(replyTopic, | |
| 151 | + Buffer.buffer(response.toString()), | |
| 152 | + MqttQoS.AT_LEAST_ONCE, | |
| 153 | + false, | |
| 154 | + false); | |
| 155 | + log.info("[handleEventPost][发送响应消息成功][topic: {}][response: {}]", | |
| 156 | + replyTopic, response.toString()); | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * 构建设备属性上报请求对象 | |
| 161 | + * | |
| 162 | + * @param jsonObject 消息内容 | |
| 163 | + * @param topicParts 主题部分 | |
| 164 | + * @return 设备属性上报请求对象 | |
| 165 | + */ | |
| 166 | + private IotDevicePropertyReportReqDTO buildPropertyReportDTO(JSONObject jsonObject, | |
| 167 | + String[] topicParts) { | |
| 168 | + return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO() | |
| 169 | + .setRequestId(jsonObject.getStr("id")) | |
| 170 | + .setProcessId(IotPluginCommonUtils.getProcessId()) | |
| 171 | + .setReportTime(LocalDateTime.now()) | |
| 172 | + .setProductKey(topicParts[2]) | |
| 173 | + .setDeviceName(topicParts[3])) | |
| 174 | + .setProperties(jsonObject.getJSONObject("params")); | |
| 175 | + } | |
| 176 | + | |
| 177 | + /** | |
| 178 | + * 构建设备事件上报请求对象 | |
| 179 | + * | |
| 180 | + * @param jsonObject 消息内容 | |
| 181 | + * @param topicParts 主题部分 | |
| 182 | + * @return 设备事件上报请求对象 | |
| 183 | + */ | |
| 184 | + private IotDeviceEventReportReqDTO buildEventReportDTO(JSONObject jsonObject, String[] topicParts) { | |
| 185 | + return ((IotDeviceEventReportReqDTO) new IotDeviceEventReportReqDTO() | |
| 186 | + .setRequestId(jsonObject.getStr("id")) | |
| 187 | + .setProcessId(IotPluginCommonUtils.getProcessId()) | |
| 188 | + .setReportTime(LocalDateTime.now()) | |
| 189 | + .setProductKey(topicParts[2]) | |
| 190 | + .setDeviceName(topicParts[3])) | |
| 191 | + .setIdentifier(topicParts[4]) | |
| 192 | + .setParams(jsonObject.getJSONObject("params")); | |
| 193 | + } | |
| 194 | +} | |
| 0 | 195 | \ No newline at end of file | ... | ... |