Commit 1b59aa9ccb26822b48fc0e4bab13ac6b44461ad6
1 parent
385cea8d
reactor:【IoT 物联网】增加 http 网络组件,接入 rocketmq 消息总线
Showing
13 changed files
with
155 additions
and
152 deletions
yudao-module-iot/yudao-module-iot-biz/pom.xml
| @@ -28,6 +28,12 @@ | @@ -28,6 +28,12 @@ | ||
| 28 | <artifactId>yudao-module-iot-api</artifactId> | 28 | <artifactId>yudao-module-iot-api</artifactId> |
| 29 | <version>${revision}</version> | 29 | <version>${revision}</version> |
| 30 | </dependency> | 30 | </dependency> |
| 31 | + <dependency> | ||
| 32 | + <groupId>cn.iocoder.boot</groupId> | ||
| 33 | + <artifactId>yudao-module-iot-core</artifactId> | ||
| 34 | + <version>${revision}</version> | ||
| 35 | + </dependency> | ||
| 36 | + | ||
| 31 | <!-- IoT 协议模块 --> | 37 | <!-- IoT 协议模块 --> |
| 32 | <dependency> | 38 | <dependency> |
| 33 | <groupId>cn.iocoder.boot</groupId> | 39 | <groupId>cn.iocoder.boot</groupId> |
| @@ -80,10 +86,11 @@ | @@ -80,10 +86,11 @@ | ||
| 80 | </dependency> | 86 | </dependency> |
| 81 | 87 | ||
| 82 | <!-- 消息队列相关 --> | 88 | <!-- 消息队列相关 --> |
| 89 | + <!-- TODO @芋艿:临时打开 --> | ||
| 83 | <dependency> | 90 | <dependency> |
| 84 | <groupId>org.apache.rocketmq</groupId> | 91 | <groupId>org.apache.rocketmq</groupId> |
| 85 | <artifactId>rocketmq-spring-boot-starter</artifactId> | 92 | <artifactId>rocketmq-spring-boot-starter</artifactId> |
| 86 | - <optional>true</optional> | 93 | +<!-- <optional>true</optional>--> |
| 87 | </dependency> | 94 | </dependency> |
| 88 | <dependency> | 95 | <dependency> |
| 89 | <groupId>org.springframework.kafka</groupId> | 96 | <groupId>org.springframework.kafka</groupId> |
| @@ -147,8 +154,6 @@ | @@ -147,8 +154,6 @@ | ||
| 147 | <!-- <artifactId>yudao-module-iot-script</artifactId>--> | 154 | <!-- <artifactId>yudao-module-iot-script</artifactId>--> |
| 148 | <!-- <version>${revision}</version>--> | 155 | <!-- <version>${revision}</version>--> |
| 149 | <!-- </dependency>--> | 156 | <!-- </dependency>--> |
| 150 | - | ||
| 151 | - | ||
| 152 | </dependencies> | 157 | </dependencies> |
| 153 | 158 | ||
| 154 | </project> | 159 | </project> |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceLogMessageConsumer.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceLogMessageBusSubscriber.java
| 1 | package cn.iocoder.yudao.module.iot.mq.consumer.device; | 1 | package cn.iocoder.yudao.module.iot.mq.consumer.device; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 3 | +import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| 4 | +import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBusSubscriber; | ||
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 4 | import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; | 6 | import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; |
| 7 | +import jakarta.annotation.PostConstruct; | ||
| 5 | import jakarta.annotation.Resource; | 8 | import jakarta.annotation.Resource; |
| 6 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 7 | -import org.springframework.context.event.EventListener; | ||
| 8 | -import org.springframework.scheduling.annotation.Async; | ||
| 9 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| @@ -15,16 +16,34 @@ import org.springframework.stereotype.Component; | @@ -15,16 +16,34 @@ import org.springframework.stereotype.Component; | ||
| 15 | */ | 16 | */ |
| 16 | @Component | 17 | @Component |
| 17 | @Slf4j | 18 | @Slf4j |
| 18 | -public class IotDeviceLogMessageConsumer { | 19 | +public class IotDeviceLogMessageBusSubscriber implements IotMessageBusSubscriber<IotDeviceMessage> { |
| 20 | + | ||
| 21 | + @Resource | ||
| 22 | + private IotMessageBus messageBus; | ||
| 19 | 23 | ||
| 20 | @Resource | 24 | @Resource |
| 21 | private IotDeviceLogService deviceLogService; | 25 | private IotDeviceLogService deviceLogService; |
| 22 | 26 | ||
| 23 | - @EventListener | ||
| 24 | - @Async | 27 | + @PostConstruct |
| 28 | + public void init() { | ||
| 29 | + messageBus.register(this); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public String getTopic() { | ||
| 34 | + return IotDeviceMessage.MESSAGE_BUS_DEVICE_MESSAGE_TOPIC; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + public String getGroup() { | ||
| 39 | + return "iot_device_log_consumer"; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + // TODO @芋艿:后续再对接这个细节逻辑; | ||
| 43 | + @Override | ||
| 25 | public void onMessage(IotDeviceMessage message) { | 44 | public void onMessage(IotDeviceMessage message) { |
| 26 | log.info("[onMessage][消息内容({})]", message); | 45 | log.info("[onMessage][消息内容({})]", message); |
| 27 | - deviceLogService.createDeviceLog(message); | 46 | +// deviceLogService.createDeviceLog(message); |
| 28 | } | 47 | } |
| 29 | 48 | ||
| 30 | } | 49 | } |
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/mq/message/IotDeviceMessage.java
| 1 | package cn.iocoder.yudao.module.iot.core.mq.message; | 1 | package cn.iocoder.yudao.module.iot.core.mq.message; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.IdUtil; | ||
| 3 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; | 4 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; |
| 4 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageTypeEnum; |
| 5 | import lombok.AllArgsConstructor; | 6 | import lombok.AllArgsConstructor; |
| @@ -8,6 +9,7 @@ import lombok.Data; | @@ -8,6 +9,7 @@ import lombok.Data; | ||
| 8 | import lombok.NoArgsConstructor; | 9 | import lombok.NoArgsConstructor; |
| 9 | 10 | ||
| 10 | import java.time.LocalDateTime; | 11 | import java.time.LocalDateTime; |
| 12 | +import java.util.Map; | ||
| 11 | 13 | ||
| 12 | // TODO @芋艿:参考阿里云的物模型,优化 IoT 上下行消息的设计,尽量保持一致(渐进式,不要一口气)! | 14 | // TODO @芋艿:参考阿里云的物模型,优化 IoT 上下行消息的设计,尽量保持一致(渐进式,不要一口气)! |
| 13 | 15 | ||
| @@ -21,6 +23,18 @@ import java.time.LocalDateTime; | @@ -21,6 +23,18 @@ import java.time.LocalDateTime; | ||
| 21 | public class IotDeviceMessage { | 23 | public class IotDeviceMessage { |
| 22 | 24 | ||
| 23 | /** | 25 | /** |
| 26 | + * 【消息总线】应用的设备消息 Topic,由 iot-gateway 发给 iot-biz 进行消费 | ||
| 27 | + */ | ||
| 28 | + public static final String MESSAGE_BUS_DEVICE_MESSAGE_TOPIC = "iot_device_message"; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 【消息总线】设备消息 Topic,由 iot-biz 发送给 iot-gateway 的某个 “server”(protocol) 进行消费 | ||
| 32 | + * | ||
| 33 | + * 其中,%s 就是该“server”(protocol) 的标识 | ||
| 34 | + */ | ||
| 35 | + public static final String MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC = MESSAGE_BUS_DEVICE_MESSAGE_TOPIC + "/%s"; | ||
| 36 | + | ||
| 37 | + /** | ||
| 24 | * 请求编号 | 38 | * 请求编号 |
| 25 | */ | 39 | */ |
| 26 | private String requestId; | 40 | private String requestId; |
| @@ -70,8 +84,41 @@ public class IotDeviceMessage { | @@ -70,8 +84,41 @@ public class IotDeviceMessage { | ||
| 70 | private LocalDateTime reportTime; | 84 | private LocalDateTime reportTime; |
| 71 | 85 | ||
| 72 | /** | 86 | /** |
| 87 | + * 服务编号,该消息由哪个消息发送 | ||
| 88 | + */ | ||
| 89 | + private String serverId; | ||
| 90 | + | ||
| 91 | + /** | ||
| 73 | * 租户编号 | 92 | * 租户编号 |
| 74 | */ | 93 | */ |
| 75 | private Long tenantId; | 94 | private Long tenantId; |
| 76 | 95 | ||
| 96 | + public IotDeviceMessage ofPropertyReport(Map<String, Object> properties) { | ||
| 97 | + this.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | ||
| 98 | + this.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); | ||
| 99 | + this.setData(properties); | ||
| 100 | + return this; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public static IotDeviceMessage of(String productKey, String deviceName, String deviceKey, | ||
| 104 | + String requestId, LocalDateTime reportTime, | ||
| 105 | + String serverId, Long tenantId) { | ||
| 106 | + if (requestId == null) { | ||
| 107 | + requestId = IdUtil.fastSimpleUUID(); | ||
| 108 | + } | ||
| 109 | + if (reportTime == null) { | ||
| 110 | + reportTime = LocalDateTime.now(); | ||
| 111 | + } | ||
| 112 | + return IotDeviceMessage.builder() | ||
| 113 | + .requestId(requestId).reportTime(reportTime) | ||
| 114 | + .productKey(productKey).deviceName(deviceName).deviceKey(deviceKey) | ||
| 115 | + .serverId(serverId).tenantId(tenantId).build(); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + // ========== Topic 相关 ========== | ||
| 119 | + | ||
| 120 | + public static String getMessageBusGatewayDeviceMessageTopic(String serverId) { | ||
| 121 | + return String.format(MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC, serverId); | ||
| 122 | + } | ||
| 123 | + | ||
| 77 | } | 124 | } |
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/mq/producer/IotDeviceMessageProducer.java
| @@ -12,18 +12,6 @@ import lombok.RequiredArgsConstructor; | @@ -12,18 +12,6 @@ import lombok.RequiredArgsConstructor; | ||
| 12 | @RequiredArgsConstructor | 12 | @RequiredArgsConstructor |
| 13 | public class IotDeviceMessageProducer { | 13 | public class IotDeviceMessageProducer { |
| 14 | 14 | ||
| 15 | - /** | ||
| 16 | - * 【消息总线】应用的设备消息 Topic,由 iot-gateway 发给 iot-biz 进行消费 | ||
| 17 | - */ | ||
| 18 | - private static final String MESSAGE_BUS_DEVICE_MESSAGE_TOPIC = "iot_device_message"; | ||
| 19 | - | ||
| 20 | - /** | ||
| 21 | - * 【消息总线】设备消息 Topic,由 iot-biz 发送给 iot-gateway 的某个 “server”(protocol) 进行消费 | ||
| 22 | - * | ||
| 23 | - * 其中,%s 就是该“server”(protocol) 的标识 | ||
| 24 | - */ | ||
| 25 | - private static final String MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC = MESSAGE_BUS_DEVICE_MESSAGE_TOPIC + "/%s"; | ||
| 26 | - | ||
| 27 | private final IotMessageBus messageBus; | 15 | private final IotMessageBus messageBus; |
| 28 | 16 | ||
| 29 | /** | 17 | /** |
| @@ -32,17 +20,17 @@ public class IotDeviceMessageProducer { | @@ -32,17 +20,17 @@ public class IotDeviceMessageProducer { | ||
| 32 | * @param message 设备消息 | 20 | * @param message 设备消息 |
| 33 | */ | 21 | */ |
| 34 | public void sendDeviceMessage(IotDeviceMessage message) { | 22 | public void sendDeviceMessage(IotDeviceMessage message) { |
| 35 | - messageBus.post(MESSAGE_BUS_DEVICE_MESSAGE_TOPIC, message); | 23 | + messageBus.post(IotDeviceMessage.MESSAGE_BUS_DEVICE_MESSAGE_TOPIC, message); |
| 36 | } | 24 | } |
| 37 | 25 | ||
| 38 | /** | 26 | /** |
| 39 | * 发送网关设备消息 | 27 | * 发送网关设备消息 |
| 40 | * | 28 | * |
| 41 | - * @param server 网关的 server 标识 | 29 | + * @param serverId 网关的 serverId 标识 |
| 42 | * @param message 设备消息 | 30 | * @param message 设备消息 |
| 43 | */ | 31 | */ |
| 44 | - public void sendGatewayDeviceMessage(String server, Object message) { | ||
| 45 | - messageBus.post(String.format(MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC, server), message); | 32 | + public void sendGatewayDeviceMessage(String serverId, Object message) { |
| 33 | + messageBus.post(IotDeviceMessage.getMessageBusGatewayDeviceMessageTopic(serverId), message); | ||
| 46 | } | 34 | } |
| 47 | 35 | ||
| 48 | } | 36 | } |
yudao-module-iot/yudao-module-iot-core/src/main/resources/META-INF/spring.factories deleted
yudao-module-iot/yudao-module-iot-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
0 → 100644
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/pom.xml
| @@ -24,6 +24,12 @@ | @@ -24,6 +24,12 @@ | ||
| 24 | <version>${revision}</version> | 24 | <version>${revision}</version> |
| 25 | </dependency> | 25 | </dependency> |
| 26 | 26 | ||
| 27 | + <dependency> | ||
| 28 | + <groupId>cn.iocoder.boot</groupId> | ||
| 29 | + <artifactId>yudao-module-iot-core</artifactId> | ||
| 30 | + <version>${revision}</version> | ||
| 31 | + </dependency> | ||
| 32 | + | ||
| 27 | <!-- IoT 协议模块 --> | 33 | <!-- IoT 协议模块 --> |
| 28 | <dependency> | 34 | <dependency> |
| 29 | <groupId>cn.iocoder.boot</groupId> | 35 | <groupId>cn.iocoder.boot</groupId> |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-http/src/main/java/cn/iocoder/yudao/module/iot/net/component/http/config/IotNetComponentHttpAutoConfiguration.java
| @@ -2,12 +2,13 @@ package cn.iocoder.yudao.module.iot.net.component.http.config; | @@ -2,12 +2,13 @@ package cn.iocoder.yudao.module.iot.net.component.http.config; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.system.SystemUtil; | 3 | import cn.hutool.system.SystemUtil; |
| 4 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; | 4 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 5 | -import cn.iocoder.yudao.module.iot.net.component.http.downstream.IotDeviceDownstreamHandlerImpl; | ||
| 6 | -import cn.iocoder.yudao.module.iot.net.component.http.upstream.IotDeviceUpstreamServer; | 5 | +import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; |
| 7 | import cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonProperties; | 6 | import cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonProperties; |
| 8 | import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler; | 7 | import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler; |
| 9 | import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry; | 8 | import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry; |
| 10 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; | 9 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; |
| 10 | +import cn.iocoder.yudao.module.iot.net.component.http.downstream.IotDeviceDownstreamHandlerImpl; | ||
| 11 | +import cn.iocoder.yudao.module.iot.net.component.http.upstream.IotDeviceUpstreamServer; | ||
| 11 | import io.vertx.core.Vertx; | 12 | import io.vertx.core.Vertx; |
| 12 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 13 | import org.springframework.beans.factory.annotation.Qualifier; | 14 | import org.springframework.beans.factory.annotation.Qualifier; |
| @@ -15,7 +16,6 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; | @@ -15,7 +16,6 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
| 15 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 16 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| 16 | import org.springframework.boot.context.event.ApplicationStartedEvent; | 17 | import org.springframework.boot.context.event.ApplicationStartedEvent; |
| 17 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 18 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 18 | -import org.springframework.context.ApplicationContext; | ||
| 19 | import org.springframework.context.annotation.Bean; | 19 | import org.springframework.context.annotation.Bean; |
| 20 | import org.springframework.context.annotation.ComponentScan; | 20 | import org.springframework.context.annotation.ComponentScan; |
| 21 | import org.springframework.context.annotation.Lazy; | 21 | import org.springframework.context.annotation.Lazy; |
| @@ -86,25 +86,14 @@ public class IotNetComponentHttpAutoConfiguration { | @@ -86,25 +86,14 @@ public class IotNetComponentHttpAutoConfiguration { | ||
| 86 | 86 | ||
| 87 | /** | 87 | /** |
| 88 | * 创建设备上行服务器 | 88 | * 创建设备上行服务器 |
| 89 | - * | ||
| 90 | - * @param vertx Vert.x 实例 | ||
| 91 | - * @param deviceUpstreamApi 设备上行 API | ||
| 92 | - * @param properties HTTP 组件配置属性 | ||
| 93 | - * @param applicationContext 应用上下文 | ||
| 94 | - * @return 设备上行服务器 | ||
| 95 | */ | 89 | */ |
| 96 | @Bean(name = "httpDeviceUpstreamServer", initMethod = "start", destroyMethod = "stop") | 90 | @Bean(name = "httpDeviceUpstreamServer", initMethod = "start", destroyMethod = "stop") |
| 97 | public IotDeviceUpstreamServer deviceUpstreamServer( | 91 | public IotDeviceUpstreamServer deviceUpstreamServer( |
| 98 | @Lazy @Qualifier("httpVertx") Vertx vertx, | 92 | @Lazy @Qualifier("httpVertx") Vertx vertx, |
| 99 | IotDeviceUpstreamApi deviceUpstreamApi, | 93 | IotDeviceUpstreamApi deviceUpstreamApi, |
| 100 | IotNetComponentHttpProperties properties, | 94 | IotNetComponentHttpProperties properties, |
| 101 | - ApplicationContext applicationContext) { | ||
| 102 | - if (log.isDebugEnabled()) { | ||
| 103 | - log.debug("HTTP 服务器配置: port={}", properties.getServerPort()); | ||
| 104 | - } else { | ||
| 105 | - log.info("HTTP 服务器将监听端口: {}", properties.getServerPort()); | ||
| 106 | - } | ||
| 107 | - return new IotDeviceUpstreamServer(vertx, properties, deviceUpstreamApi, applicationContext); | 95 | + IotDeviceMessageProducer deviceMessageProducer) { |
| 96 | + return new IotDeviceUpstreamServer(vertx, properties, deviceUpstreamApi, deviceMessageProducer); | ||
| 108 | } | 97 | } |
| 109 | 98 | ||
| 110 | /** | 99 | /** |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-http/src/main/java/cn/iocoder/yudao/module/iot/net/component/http/upstream/IotDeviceUpstreamServer.java
| 1 | package cn.iocoder.yudao.module.iot.net.component.http.upstream; | 1 | package cn.iocoder.yudao.module.iot.net.component.http.upstream; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; | 3 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | ||
| 4 | import cn.iocoder.yudao.module.iot.net.component.http.config.IotNetComponentHttpProperties; | 5 | import cn.iocoder.yudao.module.iot.net.component.http.config.IotNetComponentHttpProperties; |
| 5 | import cn.iocoder.yudao.module.iot.net.component.http.upstream.router.IotDeviceUpstreamVertxHandler; | 6 | import cn.iocoder.yudao.module.iot.net.component.http.upstream.router.IotDeviceUpstreamVertxHandler; |
| 6 | import io.vertx.core.AbstractVerticle; | 7 | import io.vertx.core.AbstractVerticle; |
| @@ -8,9 +9,8 @@ import io.vertx.core.Promise; | @@ -8,9 +9,8 @@ import io.vertx.core.Promise; | ||
| 8 | import io.vertx.core.Vertx; | 9 | import io.vertx.core.Vertx; |
| 9 | import io.vertx.ext.web.Router; | 10 | import io.vertx.ext.web.Router; |
| 10 | import io.vertx.ext.web.handler.BodyHandler; | 11 | import io.vertx.ext.web.handler.BodyHandler; |
| 12 | +import lombok.RequiredArgsConstructor; | ||
| 11 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 12 | -import org.springframework.context.ApplicationContext; | ||
| 13 | -import org.springframework.context.annotation.Lazy; | ||
| 14 | 14 | ||
| 15 | /** | 15 | /** |
| 16 | * IoT 设备上行服务器 | 16 | * IoT 设备上行服务器 |
| @@ -19,48 +19,24 @@ import org.springframework.context.annotation.Lazy; | @@ -19,48 +19,24 @@ import org.springframework.context.annotation.Lazy; | ||
| 19 | * | 19 | * |
| 20 | * @author 芋道源码 | 20 | * @author 芋道源码 |
| 21 | */ | 21 | */ |
| 22 | +@RequiredArgsConstructor | ||
| 22 | @Slf4j | 23 | @Slf4j |
| 23 | public class IotDeviceUpstreamServer extends AbstractVerticle { | 24 | public class IotDeviceUpstreamServer extends AbstractVerticle { |
| 24 | 25 | ||
| 25 | - /** | ||
| 26 | - * Vert.x 实例 | ||
| 27 | - */ | ||
| 28 | private final Vertx vertx; | 26 | private final Vertx vertx; |
| 29 | 27 | ||
| 30 | - /** | ||
| 31 | - * HTTP 组件配置属性 | ||
| 32 | - */ | ||
| 33 | private final IotNetComponentHttpProperties httpProperties; | 28 | private final IotNetComponentHttpProperties httpProperties; |
| 34 | 29 | ||
| 35 | - /** | ||
| 36 | - * 设备上行 API | ||
| 37 | - */ | ||
| 38 | private final IotDeviceUpstreamApi deviceUpstreamApi; | 30 | private final IotDeviceUpstreamApi deviceUpstreamApi; |
| 39 | 31 | ||
| 40 | - /** | ||
| 41 | - * Spring 应用上下文 | ||
| 42 | - */ | ||
| 43 | - private final ApplicationContext applicationContext; | 32 | + private final IotDeviceMessageProducer deviceMessageProducer; |
| 44 | 33 | ||
| 45 | - /** | ||
| 46 | - * 构造函数 | ||
| 47 | - * | ||
| 48 | - * @param vertx Vert.x 实例 | ||
| 49 | - * @param httpProperties HTTP 组件配置属性 | ||
| 50 | - * @param deviceUpstreamApi 设备上行 API | ||
| 51 | - * @param applicationContext Spring 应用上下文 | ||
| 52 | - */ | ||
| 53 | - public IotDeviceUpstreamServer( | ||
| 54 | - @Lazy Vertx vertx, | ||
| 55 | - IotNetComponentHttpProperties httpProperties, | ||
| 56 | - IotDeviceUpstreamApi deviceUpstreamApi, | ||
| 57 | - ApplicationContext applicationContext) { | ||
| 58 | - this.vertx = vertx; | ||
| 59 | - this.httpProperties = httpProperties; | ||
| 60 | - this.deviceUpstreamApi = deviceUpstreamApi; | ||
| 61 | - this.applicationContext = applicationContext; | 34 | + @Override |
| 35 | + public void start() throws Exception { | ||
| 36 | + start(Promise.promise()); | ||
| 62 | } | 37 | } |
| 63 | 38 | ||
| 39 | + // TODO @haohao:这样貌似初始化不到;我临时拷贝上去了 | ||
| 64 | @Override | 40 | @Override |
| 65 | public void start(Promise<Void> startPromise) { | 41 | public void start(Promise<Void> startPromise) { |
| 66 | // 创建路由 | 42 | // 创建路由 |
| @@ -69,7 +45,7 @@ public class IotDeviceUpstreamServer extends AbstractVerticle { | @@ -69,7 +45,7 @@ public class IotDeviceUpstreamServer extends AbstractVerticle { | ||
| 69 | 45 | ||
| 70 | // 创建处理器 | 46 | // 创建处理器 |
| 71 | IotDeviceUpstreamVertxHandler upstreamHandler = new IotDeviceUpstreamVertxHandler( | 47 | IotDeviceUpstreamVertxHandler upstreamHandler = new IotDeviceUpstreamVertxHandler( |
| 72 | - deviceUpstreamApi, applicationContext); | 48 | + deviceUpstreamApi, deviceMessageProducer); |
| 73 | 49 | ||
| 74 | // 添加路由处理器 | 50 | // 添加路由处理器 |
| 75 | router.post(IotDeviceUpstreamVertxHandler.PROPERTY_PATH).handler(upstreamHandler::handle); | 51 | router.post(IotDeviceUpstreamVertxHandler.PROPERTY_PATH).handler(upstreamHandler::handle); |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-http/src/main/java/cn/iocoder/yudao/module/iot/net/component/http/upstream/router/IotDeviceUpstreamVertxHandler.java
| @@ -8,17 +8,16 @@ import cn.hutool.core.util.StrUtil; | @@ -8,17 +8,16 @@ import cn.hutool.core.util.StrUtil; | ||
| 8 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 8 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 9 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; | 9 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 10 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO; | 10 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceEventReportReqDTO; |
| 11 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO; | ||
| 12 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO; | ||
| 13 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | 11 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 12 | +import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | ||
| 14 | import cn.iocoder.yudao.module.iot.net.component.core.constants.IotDeviceTopicEnum; | 13 | import cn.iocoder.yudao.module.iot.net.component.core.constants.IotDeviceTopicEnum; |
| 15 | import cn.iocoder.yudao.module.iot.net.component.core.pojo.IotStandardResponse; | 14 | import cn.iocoder.yudao.module.iot.net.component.core.pojo.IotStandardResponse; |
| 16 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; | 15 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; |
| 17 | import io.vertx.core.Handler; | 16 | import io.vertx.core.Handler; |
| 18 | import io.vertx.core.json.JsonObject; | 17 | import io.vertx.core.json.JsonObject; |
| 19 | import io.vertx.ext.web.RoutingContext; | 18 | import io.vertx.ext.web.RoutingContext; |
| 19 | +import lombok.RequiredArgsConstructor; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| 21 | -import org.springframework.context.ApplicationContext; | ||
| 22 | 21 | ||
| 23 | import java.time.LocalDateTime; | 22 | import java.time.LocalDateTime; |
| 24 | import java.util.Map; | 23 | import java.util.Map; |
| @@ -33,6 +32,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC | @@ -33,6 +32,7 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC | ||
| 33 | * | 32 | * |
| 34 | * @author 芋道源码 | 33 | * @author 芋道源码 |
| 35 | */ | 34 | */ |
| 35 | +@RequiredArgsConstructor | ||
| 36 | @Slf4j | 36 | @Slf4j |
| 37 | public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | 37 | public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { |
| 38 | 38 | ||
| @@ -70,17 +70,10 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | @@ -70,17 +70,10 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | ||
| 70 | * 设备上行 API | 70 | * 设备上行 API |
| 71 | */ | 71 | */ |
| 72 | private final IotDeviceUpstreamApi deviceUpstreamApi; | 72 | private final IotDeviceUpstreamApi deviceUpstreamApi; |
| 73 | - | ||
| 74 | /** | 73 | /** |
| 75 | - * 构造函数 | ||
| 76 | - * | ||
| 77 | - * @param deviceUpstreamApi 设备上行 API | ||
| 78 | - * @param applicationContext 应用上下文 | 74 | + * 设备消息生产者 |
| 79 | */ | 75 | */ |
| 80 | - public IotDeviceUpstreamVertxHandler(IotDeviceUpstreamApi deviceUpstreamApi, | ||
| 81 | - ApplicationContext applicationContext) { | ||
| 82 | - this.deviceUpstreamApi = deviceUpstreamApi; | ||
| 83 | - } | 76 | + private final IotDeviceMessageProducer deviceMessageProducer; |
| 84 | 77 | ||
| 85 | @Override | 78 | @Override |
| 86 | public void handle(RoutingContext routingContext) { | 79 | public void handle(RoutingContext routingContext) { |
| @@ -170,18 +163,17 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | @@ -170,18 +163,17 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | ||
| 170 | */ | 163 | */ |
| 171 | private void handlePropertyPost(RoutingContext routingContext, String productKey, String deviceName, | 164 | private void handlePropertyPost(RoutingContext routingContext, String productKey, String deviceName, |
| 172 | String requestId, JsonObject body) { | 165 | String requestId, JsonObject body) { |
| 173 | - // 处理属性上报 | ||
| 174 | - IotDevicePropertyReportReqDTO reportReqDTO = parsePropertyReportRequest(productKey, deviceName, | ||
| 175 | - requestId, body); | ||
| 176 | - | ||
| 177 | - // 设备上线 | ||
| 178 | - updateDeviceState(reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); | ||
| 179 | - | ||
| 180 | - // 属性上报 | ||
| 181 | - CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceProperty(reportReqDTO); | ||
| 182 | - | ||
| 183 | - // 返回响应 | ||
| 184 | - sendResponse(routingContext, requestId, PROPERTY_METHOD, result); | 166 | + // 1.1 构建设备消息 |
| 167 | + String deviceKey = "xxx"; // TODO @芋艿:待支持 | ||
| 168 | + Long tenantId = 1L; // TODO @芋艿:待支持 | ||
| 169 | + IotDeviceMessage message = IotDeviceMessage.of(productKey, deviceName, deviceKey, | ||
| 170 | + requestId, LocalDateTime.now(), IotNetComponentCommonUtils.getProcessId(), tenantId) | ||
| 171 | + .ofPropertyReport(parsePropertiesFromBody(body)); | ||
| 172 | + // 1.2 发送消息 | ||
| 173 | + deviceMessageProducer.sendDeviceMessage(message); | ||
| 174 | + | ||
| 175 | + // 2. 返回响应 | ||
| 176 | + sendResponse(routingContext, requestId, PROPERTY_METHOD, null); | ||
| 185 | } | 177 | } |
| 186 | 178 | ||
| 187 | /** | 179 | /** |
| @@ -200,9 +192,6 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | @@ -200,9 +192,6 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | ||
| 200 | IotDeviceEventReportReqDTO reportReqDTO = parseEventReportRequest(productKey, deviceName, identifier, | 192 | IotDeviceEventReportReqDTO reportReqDTO = parseEventReportRequest(productKey, deviceName, identifier, |
| 201 | requestId, body); | 193 | requestId, body); |
| 202 | 194 | ||
| 203 | - // 设备上线 | ||
| 204 | - updateDeviceState(reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); | ||
| 205 | - | ||
| 206 | // 事件上报 | 195 | // 事件上报 |
| 207 | CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceEvent(reportReqDTO); | 196 | CommonResult<Boolean> result = deviceUpstreamApi.reportDeviceEvent(reportReqDTO); |
| 208 | String method = EVENT_METHOD_PREFIX + identifier + EVENT_METHOD_SUFFIX; | 197 | String method = EVENT_METHOD_PREFIX + identifier + EVENT_METHOD_SUFFIX; |
| @@ -221,8 +210,11 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | @@ -221,8 +210,11 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | ||
| 221 | */ | 210 | */ |
| 222 | private void sendResponse(RoutingContext routingContext, String requestId, String method, | 211 | private void sendResponse(RoutingContext routingContext, String requestId, String method, |
| 223 | CommonResult<Boolean> result) { | 212 | CommonResult<Boolean> result) { |
| 213 | + // TODO @芋艿:后续再优化 | ||
| 224 | IotStandardResponse response; | 214 | IotStandardResponse response; |
| 225 | - if (result.isSuccess()) { | 215 | + if (result == null ) { |
| 216 | + response = IotStandardResponse.success(requestId, method, null); | ||
| 217 | + } else if (result.isSuccess()) { | ||
| 226 | response = IotStandardResponse.success(requestId, method, result.getData()); | 218 | response = IotStandardResponse.success(requestId, method, result.getData()); |
| 227 | } else { | 219 | } else { |
| 228 | response = IotStandardResponse.error(requestId, method, result.getCode(), result.getMsg()); | 220 | response = IotStandardResponse.error(requestId, method, result.getCode(), result.getMsg()); |
| @@ -265,45 +257,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | @@ -265,45 +257,7 @@ public class IotDeviceUpstreamVertxHandler implements Handler<RoutingContext> { | ||
| 265 | EVENT_METHOD_SUFFIX; | 257 | EVENT_METHOD_SUFFIX; |
| 266 | } | 258 | } |
| 267 | 259 | ||
| 268 | - /** | ||
| 269 | - * 更新设备状态 | ||
| 270 | - * | ||
| 271 | - * @param productKey 产品 Key | ||
| 272 | - * @param deviceName 设备名称 | ||
| 273 | - */ | ||
| 274 | - private void updateDeviceState(String productKey, String deviceName) { | ||
| 275 | - IotDeviceStateUpdateReqDTO reqDTO = ((IotDeviceStateUpdateReqDTO) new IotDeviceStateUpdateReqDTO() | ||
| 276 | - .setRequestId(IdUtil.fastSimpleUUID()) | ||
| 277 | - .setProcessId(IotNetComponentCommonUtils.getProcessId()) | ||
| 278 | - .setReportTime(LocalDateTime.now()) | ||
| 279 | - .setProductKey(productKey) | ||
| 280 | - .setDeviceName(deviceName)).setState(IotDeviceStateEnum.ONLINE.getState()); | ||
| 281 | - deviceUpstreamApi.updateDeviceState(reqDTO); | ||
| 282 | - } | ||
| 283 | - | ||
| 284 | - /** | ||
| 285 | - * 解析属性上报请求 | ||
| 286 | - * | ||
| 287 | - * @param productKey 产品 Key | ||
| 288 | - * @param deviceName 设备名称 | ||
| 289 | - * @param requestId 请求 ID | ||
| 290 | - * @param body 请求体 | ||
| 291 | - * @return 属性上报请求 DTO | ||
| 292 | - */ | ||
| 293 | - private IotDevicePropertyReportReqDTO parsePropertyReportRequest(String productKey, String deviceName, | ||
| 294 | - String requestId, JsonObject body) { | ||
| 295 | - // 解析属性 | ||
| 296 | - Map<String, Object> properties = parsePropertiesFromBody(body); | ||
| 297 | - | ||
| 298 | - // 构建属性上报请求 DTO | ||
| 299 | - return ((IotDevicePropertyReportReqDTO) new IotDevicePropertyReportReqDTO() | ||
| 300 | - .setRequestId(requestId) | ||
| 301 | - .setProcessId(IotNetComponentCommonUtils.getProcessId()) | ||
| 302 | - .setReportTime(LocalDateTime.now()) | ||
| 303 | - .setProductKey(productKey) | ||
| 304 | - .setDeviceName(deviceName)).setProperties(properties); | ||
| 305 | - } | ||
| 306 | - | 260 | + // TODO @芋艿:这块在看看 |
| 307 | /** | 261 | /** |
| 308 | * 从请求体解析属性 | 262 | * 从请求体解析属性 |
| 309 | * | 263 | * |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/pom.xml
| @@ -50,6 +50,12 @@ | @@ -50,6 +50,12 @@ | ||
| 50 | <version>${revision}</version> | 50 | <version>${revision}</version> |
| 51 | </dependency> | 51 | </dependency> |
| 52 | 52 | ||
| 53 | + <!-- TODO @芋艿:消息队列,后续可能去掉,默认不使用 rocketmq --> | ||
| 54 | + <dependency> | ||
| 55 | + <groupId>org.apache.rocketmq</groupId> | ||
| 56 | + <artifactId>rocketmq-spring-boot-starter</artifactId> | ||
| 57 | + </dependency> | ||
| 58 | + | ||
| 53 | </dependencies> | 59 | </dependencies> |
| 54 | 60 | ||
| 55 | <build> | 61 | <build> |
| @@ -72,4 +78,4 @@ | @@ -72,4 +78,4 @@ | ||
| 72 | </plugins> | 78 | </plugins> |
| 73 | </build> | 79 | </build> |
| 74 | 80 | ||
| 75 | -</project> | ||
| 76 | \ No newline at end of file | 81 | \ No newline at end of file |
| 82 | +</project> | ||
| 77 | \ No newline at end of file | 83 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/resources/application.yml
| @@ -26,13 +26,13 @@ yudao: | @@ -26,13 +26,13 @@ yudao: | ||
| 26 | upstream-url: http://127.0.0.1:48080 # 主程序 API 地址 | 26 | upstream-url: http://127.0.0.1:48080 # 主程序 API 地址 |
| 27 | upstream-connect-timeout: 30s # 连接超时 | 27 | upstream-connect-timeout: 30s # 连接超时 |
| 28 | upstream-read-timeout: 30s # 读取超时 | 28 | upstream-read-timeout: 30s # 读取超时 |
| 29 | - | 29 | + |
| 30 | # 下行通信配置,用于接收主程序的控制指令 | 30 | # 下行通信配置,用于接收主程序的控制指令 |
| 31 | downstream-port: 18888 # 下行服务器端口 | 31 | downstream-port: 18888 # 下行服务器端口 |
| 32 | - | 32 | + |
| 33 | # 组件服务唯一标识 | 33 | # 组件服务唯一标识 |
| 34 | server-key: yudao-module-iot-net-component-server | 34 | server-key: yudao-module-iot-net-component-server |
| 35 | - | 35 | + |
| 36 | # 心跳频率,单位:毫秒 | 36 | # 心跳频率,单位:毫秒 |
| 37 | heartbeat-interval: 30000 | 37 | heartbeat-interval: 30000 |
| 38 | 38 | ||
| @@ -50,15 +50,26 @@ yudao: | @@ -50,15 +50,26 @@ yudao: | ||
| 50 | enabled: true # 启用EMQX组件 | 50 | enabled: true # 启用EMQX组件 |
| 51 | mqtt-host: 127.0.0.1 # MQTT服务器主机地址 | 51 | mqtt-host: 127.0.0.1 # MQTT服务器主机地址 |
| 52 | mqtt-port: 1883 # MQTT服务器端口 | 52 | mqtt-port: 1883 # MQTT服务器端口 |
| 53 | - mqtt-username: yudao # MQTT服务器用户名 | ||
| 54 | - mqtt-password: 123456 # MQTT服务器密码 | 53 | + mqtt-username: admin # MQTT服务器用户名 |
| 54 | + mqtt-password: admin123 # MQTT服务器密码 | ||
| 55 | mqtt-ssl: false # 是否启用SSL | 55 | mqtt-ssl: false # 是否启用SSL |
| 56 | mqtt-topics: # 订阅的主题列表 | 56 | mqtt-topics: # 订阅的主题列表 |
| 57 | - "/sys/#" | 57 | - "/sys/#" |
| 58 | auth-port: 8101 # 认证端口 | 58 | auth-port: 8101 # 认证端口 |
| 59 | + message-bus: | ||
| 60 | + type: rocketmq # 消息总线的类型 | ||
| 59 | 61 | ||
| 60 | # 日志配置 | 62 | # 日志配置 |
| 61 | logging: | 63 | logging: |
| 62 | level: | 64 | level: |
| 63 | cn.iocoder.yudao: INFO | 65 | cn.iocoder.yudao: INFO |
| 64 | - root: INFO | ||
| 65 | \ No newline at end of file | 66 | \ No newline at end of file |
| 67 | + root: INFO | ||
| 68 | + | ||
| 69 | +--- #################### 消息队列相关 #################### | ||
| 70 | + | ||
| 71 | +# rocketmq 配置项,对应 RocketMQProperties 配置类 | ||
| 72 | +rocketmq: | ||
| 73 | + name-server: 127.0.0.1:9876 # RocketMQ Namesrv | ||
| 74 | + # Producer 配置项 | ||
| 75 | + producer: | ||
| 76 | + group: ${spring.application.name}_PRODUCER # 生产者分组 |
yudao-server/src/main/resources/application.yaml
| @@ -311,6 +311,9 @@ yudao: | @@ -311,6 +311,9 @@ yudao: | ||
| 311 | kd100: | 311 | kd100: |
| 312 | key: pLXUGAwK5305 | 312 | key: pLXUGAwK5305 |
| 313 | customer: E77DF18BE109F454A5CD319E44BF5177 | 313 | customer: E77DF18BE109F454A5CD319E44BF5177 |
| 314 | + iot: | ||
| 315 | + message-bus: | ||
| 316 | + type: rocketmq # 消息总线的类型 | ||
| 314 | 317 | ||
| 315 | debug: false | 318 | debug: false |
| 316 | # 插件配置 TODO 芋艿:【IOT】需要处理下 | 319 | # 插件配置 TODO 芋艿:【IOT】需要处理下 |