|
|
@@ -1,9 +1,7 @@
|
|
|
package cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.router;
|
|
|
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
|
|
|
-import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
|
|
|
import cn.iocoder.yudao.module.iot.gateway.enums.IotDeviceTopicEnum;
|
|
|
import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
|
|
|
import io.vertx.mqtt.messages.MqttPublishMessage;
|
|
|
@@ -19,14 +17,12 @@ import java.nio.charset.StandardCharsets;
|
|
|
* @author 芋道源码
|
|
|
*/
|
|
|
@Slf4j
|
|
|
-public class IotMqttUpstreamHandler {
|
|
|
+public class IotMqttUpstreamHandler extends IotMqttAbstractHandler {
|
|
|
|
|
|
- private final IotDeviceMessageProducer deviceMessageProducer;
|
|
|
private final IotDeviceMessageService deviceMessageService;
|
|
|
private final String serverId;
|
|
|
|
|
|
public IotMqttUpstreamHandler(cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttUpstreamProtocol protocol) {
|
|
|
- this.deviceMessageProducer = SpringUtil.getBean(IotDeviceMessageProducer.class);
|
|
|
this.deviceMessageService = SpringUtil.getBean(IotDeviceMessageService.class);
|
|
|
this.serverId = protocol.getServerId();
|
|
|
}
|
|
|
@@ -38,41 +34,22 @@ public class IotMqttUpstreamHandler {
|
|
|
String topic = message.topicName();
|
|
|
String payload = message.payload().toString(StandardCharsets.UTF_8);
|
|
|
|
|
|
- if (StrUtil.isBlank(topic)) {
|
|
|
- log.warn("[handle][主题为空,忽略消息]");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (StrUtil.isBlank(payload)) {
|
|
|
- log.warn("[handle][消息内容为空][topic: {}]", topic);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
log.debug("[handle][收到 MQTT 消息][topic: {}]", topic);
|
|
|
+ // 调用父类的 handle 方法,父类会进行参数校验
|
|
|
handle(topic, payload);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 处理 MQTT 消息
|
|
|
- *
|
|
|
- * @param topic 主题
|
|
|
- * @param payload 消息内容
|
|
|
- */
|
|
|
- public void handle(String topic, String payload) {
|
|
|
- try {
|
|
|
- // 1. 识别并验证消息类型
|
|
|
- String messageType = getMessageType(topic);
|
|
|
- if (messageType == null) {
|
|
|
- log.warn("[handle][未知的消息类型][topic: {}]", topic);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 处理消息
|
|
|
- processMessage(topic, payload, messageType);
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("[handle][处理消息失败][topic: {}][payload: {}]", topic, payload, e);
|
|
|
+ @Override
|
|
|
+ protected void doHandle(String topic, String payload) {
|
|
|
+ // 1. 识别并验证消息类型
|
|
|
+ String messageType = getMessageType(topic);
|
|
|
+ if (messageType == null) {
|
|
|
+ log.warn("[doHandle][未知的消息类型][topic: {}]", topic);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ // 2. 处理消息
|
|
|
+ processMessage(topic, payload, messageType);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -109,39 +86,37 @@ public class IotMqttUpstreamHandler {
|
|
|
* @return 消息类型描述,如果不支持返回 null
|
|
|
*/
|
|
|
private String getMessageType(String topic) {
|
|
|
- if (StrUtil.isBlank(topic)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
+ // 此方法由 doHandle 调用,topic 已经在父类中校验过,无需重复校验
|
|
|
|
|
|
// 按优先级匹配主题类型,避免误匹配
|
|
|
|
|
|
- // 1. 设备属性上报: /sys/{productKey}/{deviceName}/thing/event/property/post
|
|
|
+ // 1. 设备属性上报: /sys/{productKey}/{deviceName}/thing/property/post
|
|
|
if (isPropertyPostTopic(topic)) {
|
|
|
return IotDeviceTopicEnum.PROPERTY_POST_TOPIC.getDescription();
|
|
|
}
|
|
|
|
|
|
- // 2. 设备事件上报: /sys/{productKey}/{deviceName}/thing/event/{eventIdentifier}/post
|
|
|
+ // 2. 设备事件上报: /sys/{productKey}/{deviceName}/thing/{eventIdentifier}/post
|
|
|
if (isEventPostTopic(topic)) {
|
|
|
return "设备事件上报";
|
|
|
}
|
|
|
|
|
|
- // 3. 设备属性设置响应: /sys/{productKey}/{deviceName}/thing/service/property/set_reply
|
|
|
+ // 3. 设备属性设置响应: /sys/{productKey}/{deviceName}/thing/property/set_reply
|
|
|
if (isPropertySetReplyTopic(topic)) {
|
|
|
return "设备属性设置响应";
|
|
|
}
|
|
|
|
|
|
- // 4. 设备属性获取响应: /sys/{productKey}/{deviceName}/thing/service/property/get_reply
|
|
|
+ // 4. 设备属性获取响应: /sys/{productKey}/{deviceName}/thing/property/get_reply
|
|
|
if (isPropertyGetReplyTopic(topic)) {
|
|
|
return "设备属性获取响应";
|
|
|
}
|
|
|
|
|
|
- // 5. 设备配置设置响应: /sys/{productKey}/{deviceName}/thing/service/config/set_reply
|
|
|
+ // 5. 设备配置设置响应: /sys/{productKey}/{deviceName}/thing/config/set_reply
|
|
|
if (isConfigSetReplyTopic(topic)) {
|
|
|
return IotDeviceTopicEnum.CONFIG_SET_TOPIC.getDescription() + "响应";
|
|
|
}
|
|
|
|
|
|
// 6. 设备 OTA 升级响应:
|
|
|
- // /sys/{productKey}/{deviceName}/thing/service/ota/upgrade_reply
|
|
|
+ // /sys/{productKey}/{deviceName}/thing/ota/upgrade_reply
|
|
|
if (isOtaUpgradeReplyTopic(topic)) {
|
|
|
return IotDeviceTopicEnum.OTA_UPGRADE_TOPIC.getDescription() + "响应";
|
|
|
}
|
|
|
@@ -214,18 +189,4 @@ public class IotMqttUpstreamHandler {
|
|
|
&& !topic.contains("ota");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 解析主题,获取主题各部分
|
|
|
- *
|
|
|
- * @param topic 主题
|
|
|
- * @return 主题各部分数组,如果解析失败返回 null
|
|
|
- */
|
|
|
- private String[] parseTopic(String topic) {
|
|
|
- String[] topicParts = topic.split("/");
|
|
|
- if (topicParts.length < 7) {
|
|
|
- log.warn("[parseTopic][主题格式不正确][topic: {}]", topic);
|
|
|
- return null;
|
|
|
- }
|
|
|
- return topicParts;
|
|
|
- }
|
|
|
}
|