Commit 02c3aa748b8ed45be1c438cdc91563422b388606

Authored by YunaiV
1 parent b4035cb0

reactor:【IoT 物联网】清理心跳逻辑

Showing 25 changed files with 168 additions and 1323 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/IotDeviceUpstreamApi.java
@@ -80,14 +80,4 @@ public interface IotDeviceUpstreamApi { @@ -80,14 +80,4 @@ public interface IotDeviceUpstreamApi {
80 @PostMapping(PREFIX + "/authenticate-emqx-connection") 80 @PostMapping(PREFIX + "/authenticate-emqx-connection")
81 CommonResult<Boolean> authenticateEmqxConnection(@Valid @RequestBody IotDeviceEmqxAuthReqDTO authReqDTO); 81 CommonResult<Boolean> authenticateEmqxConnection(@Valid @RequestBody IotDeviceEmqxAuthReqDTO authReqDTO);
82 82
83 - // ========== 插件相关 ==========  
84 -  
85 - /**  
86 - * 心跳插件实例  
87 - *  
88 - * @param heartbeatReqDTO 心跳插件实例 DTO  
89 - */  
90 - @PostMapping(PREFIX + "/heartbeat-plugin-instance")  
91 - CommonResult<Boolean> heartbeatPluginInstance(@Valid @RequestBody IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO);  
92 -  
93 } 83 }
94 \ No newline at end of file 84 \ No newline at end of file
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotPluginInstanceHeartbeatReqDTO.java deleted
1 -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream;  
2 -  
3 -import jakarta.validation.constraints.NotEmpty;  
4 -import jakarta.validation.constraints.NotNull;  
5 -import lombok.Data;  
6 -  
7 -/**  
8 - * IoT 插件实例心跳 Request DTO  
9 - *  
10 - * @author 芋道源码  
11 - */  
12 -@Data  
13 -public class IotPluginInstanceHeartbeatReqDTO {  
14 -  
15 - /**  
16 - * 请求编号  
17 - */  
18 - @NotEmpty(message = "请求编号不能为空")  
19 - private String processId;  
20 -  
21 - /**  
22 - * 插件包标识符  
23 - */  
24 - @NotEmpty(message = "插件包标识符不能为空")  
25 - private String pluginKey;  
26 -  
27 - /**  
28 - * 插件实例所在 IP  
29 - */  
30 - @NotEmpty(message = "插件实例所在 IP 不能为空")  
31 - private String hostIp;  
32 - /**  
33 - * 插件实例的进程编号  
34 - */  
35 - @NotNull(message = "插件实例的进程编号不能为空")  
36 - private Integer downstreamPort;  
37 -  
38 - /**  
39 - * 是否在线  
40 - */  
41 - @NotNull(message = "是否在线不能为空")  
42 - private Boolean online;  
43 -  
44 -}  
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java
@@ -21,8 +21,6 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi { @@ -21,8 +21,6 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi {
21 21
22 @Resource 22 @Resource
23 private IotDeviceUpstreamService deviceUpstreamService; 23 private IotDeviceUpstreamService deviceUpstreamService;
24 - @Resource  
25 - private IotPluginInstanceService pluginInstanceService;  
26 24
27 // ========== 设备相关 ========== 25 // ========== 设备相关 ==========
28 26
@@ -68,12 +66,4 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi { @@ -68,12 +66,4 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi {
68 return success(result); 66 return success(result);
69 } 67 }
70 68
71 - // ========== 插件相关 ==========  
72 -  
73 - @Override  
74 - public CommonResult<Boolean> heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {  
75 - pluginInstanceService.heartbeatPluginInstance(heartbeatReqDTO);  
76 - return success(true);  
77 - }  
78 -  
79 } 69 }
80 \ No newline at end of file 70 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java
1 package cn.iocoder.yudao.module.iot.service.plugin; 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2
3 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;  
4 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; 3 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
6 import org.springframework.web.multipart.MultipartFile; 5 import org.springframework.web.multipart.MultipartFile;
@@ -15,13 +14,6 @@ import java.time.LocalDateTime; @@ -15,13 +14,6 @@ import java.time.LocalDateTime;
15 public interface IotPluginInstanceService { 14 public interface IotPluginInstanceService {
16 15
17 /** 16 /**
18 - * 心跳插件实例  
19 - *  
20 - * @param heartbeatReqDTO 心跳插件实例 DTO  
21 - */  
22 - void heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO);  
23 -  
24 - /**  
25 * 离线超时插件实例 17 * 离线超时插件实例
26 * 18 *
27 * @param maxHeartbeatTime 最大心跳时间 19 * @param maxHeartbeatTime 最大心跳时间
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java
@@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.iot.service.plugin; @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.iot.service.plugin;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;  
6 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;  
7 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
8 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
9 import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper; 7 import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper;
@@ -11,7 +9,6 @@ import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDA @@ -11,7 +9,6 @@ import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDA
11 import jakarta.annotation.Resource; 9 import jakarta.annotation.Resource;
12 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
13 import org.springframework.beans.factory.annotation.Value; 11 import org.springframework.beans.factory.annotation.Value;
14 -import org.springframework.context.annotation.Lazy;  
15 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
16 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
17 import org.springframework.web.multipart.MultipartFile; 14 import org.springframework.web.multipart.MultipartFile;
@@ -32,10 +29,6 @@ import java.util.concurrent.TimeUnit; @@ -32,10 +29,6 @@ import java.util.concurrent.TimeUnit;
32 public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { 29 public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
33 30
34 @Resource 31 @Resource
35 - @Lazy // 延迟加载,避免循环依赖  
36 - private IotPluginConfigService pluginConfigService;  
37 -  
38 - @Resource  
39 private IotPluginInstanceMapper pluginInstanceMapper; 32 private IotPluginInstanceMapper pluginInstanceMapper;
40 33
41 @Resource 34 @Resource
@@ -48,47 +41,6 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { @@ -48,47 +41,6 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
48 private String pluginsDir; 41 private String pluginsDir;
49 42
50 @Override 43 @Override
51 - public void heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {  
52 - // 情况一:已存在,则进行更新  
53 - IotPluginInstanceDO instance = TenantUtils.executeIgnore(  
54 - () -> pluginInstanceMapper.selectByProcessId(heartbeatReqDTO.getProcessId()));  
55 - if (instance != null) {  
56 - IotPluginInstanceDO.IotPluginInstanceDOBuilder updateObj = IotPluginInstanceDO.builder().id(instance.getId())  
57 - .hostIp(heartbeatReqDTO.getHostIp()).downstreamPort(heartbeatReqDTO.getDownstreamPort())  
58 - .online(heartbeatReqDTO.getOnline()).heartbeatTime(LocalDateTime.now());  
59 - if (Boolean.TRUE.equals(heartbeatReqDTO.getOnline())) {  
60 - if (Boolean.FALSE.equals(instance.getOnline())) { // 当前处于离线时,才需要更新上线时间  
61 - updateObj.onlineTime(LocalDateTime.now());  
62 - }  
63 - } else {  
64 - updateObj.offlineTime(LocalDateTime.now());  
65 - }  
66 - TenantUtils.execute(instance.getTenantId(),  
67 - () -> pluginInstanceMapper.updateById(updateObj.build()));  
68 - return;  
69 - }  
70 -  
71 - // 情况二:不存在,则创建  
72 - IotPluginConfigDO info = TenantUtils.executeIgnore(  
73 - () -> pluginConfigService.getPluginConfigByPluginKey(heartbeatReqDTO.getPluginKey()));  
74 - if (info == null) {  
75 - log.error("[heartbeatPluginInstance][心跳({}) 对应的插件不存在]", heartbeatReqDTO);  
76 - return;  
77 - }  
78 - IotPluginInstanceDO.IotPluginInstanceDOBuilder insertObj = IotPluginInstanceDO.builder()  
79 - .pluginId(info.getId()).processId(heartbeatReqDTO.getProcessId())  
80 - .hostIp(heartbeatReqDTO.getHostIp()).downstreamPort(heartbeatReqDTO.getDownstreamPort())  
81 - .online(heartbeatReqDTO.getOnline()).heartbeatTime(LocalDateTime.now());  
82 - if (Boolean.TRUE.equals(heartbeatReqDTO.getOnline())) {  
83 - insertObj.onlineTime(LocalDateTime.now());  
84 - } else {  
85 - insertObj.offlineTime(LocalDateTime.now());  
86 - }  
87 - TenantUtils.execute(info.getTenantId(),  
88 - () -> pluginInstanceMapper.insert(insertObj.build()));  
89 - }  
90 -  
91 - @Override  
92 public int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime) { 44 public int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime) {
93 List<IotPluginInstanceDO> list = pluginInstanceMapper.selectListByHeartbeatTimeLt(maxHeartbeatTime); 45 List<IotPluginInstanceDO> list = pluginInstanceMapper.selectListByHeartbeatTimeLt(maxHeartbeatTime);
94 if (CollUtil.isEmpty(list)) { 46 if (CollUtil.isEmpty(list)) {
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/config/IotNetComponentCommonAutoConfiguration.java
1 package cn.iocoder.yudao.module.iot.net.component.core.config; 1 package cn.iocoder.yudao.module.iot.net.component.core.config;
2 2
3 -import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;  
4 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
5 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamServer;  
6 -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentInstanceHeartbeatJob;  
7 -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry;  
8 import cn.iocoder.yudao.module.iot.net.component.core.upstream.IotDeviceUpstreamClient; 3 import cn.iocoder.yudao.module.iot.net.component.core.upstream.IotDeviceUpstreamClient;
9 -import org.springframework.beans.factory.annotation.Qualifier;  
10 import org.springframework.boot.autoconfigure.AutoConfiguration; 4 import org.springframework.boot.autoconfigure.AutoConfiguration;
11 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
12 import org.springframework.boot.context.properties.EnableConfigurationProperties; 5 import org.springframework.boot.context.properties.EnableConfigurationProperties;
13 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Bean;
14 import org.springframework.scheduling.annotation.EnableScheduling; 7 import org.springframework.scheduling.annotation.EnableScheduling;
15 8
16 -// TODO @haohao:应该不用写 spring.factories 拉,因为被 imports 替代啦  
17 /** 9 /**
18 * IoT 网络组件的通用自动配置类 10 * IoT 网络组件的通用自动配置类
19 * 11 *
@@ -25,37 +17,11 @@ import org.springframework.scheduling.annotation.EnableScheduling; @@ -25,37 +17,11 @@ import org.springframework.scheduling.annotation.EnableScheduling;
25 public class IotNetComponentCommonAutoConfiguration { 17 public class IotNetComponentCommonAutoConfiguration {
26 18
27 /** 19 /**
28 - * 创建 EMQX 设备下行服务器  
29 - * <p>  
30 - * 当 yudao.iot.component.emqx.enabled = true 时,优先使用 emqxDeviceDownstreamHandler  
31 - */  
32 - @Bean  
33 - @ConditionalOnProperty(prefix = "yudao.iot.component.emqx", name = "enabled", havingValue = "true")  
34 - public IotDeviceDownstreamServer emqxDeviceDownstreamServer(  
35 - IotNetComponentCommonProperties properties,  
36 - @Qualifier("emqxDeviceDownstreamHandler") IotDeviceDownstreamHandler deviceDownstreamHandler) {  
37 - return new IotDeviceDownstreamServer(properties, deviceDownstreamHandler);  
38 - }  
39 -  
40 - /**  
41 - * 创建网络组件实例心跳任务  
42 - */  
43 - @Bean(initMethod = "init", destroyMethod = "stop")  
44 - public IotNetComponentInstanceHeartbeatJob pluginInstanceHeartbeatJob(  
45 - IotDeviceUpstreamApi deviceUpstreamApi,  
46 - IotNetComponentCommonProperties commonProperties,  
47 - IotNetComponentRegistry componentRegistry) {  
48 - return new IotNetComponentInstanceHeartbeatJob(  
49 - deviceUpstreamApi,  
50 - commonProperties,  
51 - componentRegistry);  
52 - }  
53 -  
54 - /**  
55 * 创建设备上行客户端 20 * 创建设备上行客户端
56 */ 21 */
57 @Bean 22 @Bean
58 public IotDeviceUpstreamClient deviceUpstreamClient() { 23 public IotDeviceUpstreamClient deviceUpstreamClient() {
59 return new IotDeviceUpstreamClient(); 24 return new IotDeviceUpstreamClient();
60 } 25 }
  26 +
61 } 27 }
62 \ No newline at end of file 28 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/config/IotNetComponentCommonProperties.java
@@ -21,38 +21,4 @@ public class IotNetComponentCommonProperties { @@ -21,38 +21,4 @@ public class IotNetComponentCommonProperties {
21 */ 21 */
22 private String pluginKey; 22 private String pluginKey;
23 23
24 - /**  
25 - * 组件实例心跳超时时间,单位:毫秒  
26 - * <p>  
27 - * 默认值:30 秒  
28 - */  
29 - private Long instanceHeartbeatTimeout = 30000L;  
30 -  
31 - /**  
32 - * 网络组件消息转发配置  
33 - */  
34 - // private ForwardMessage forwardMessage = new ForwardMessage();  
35 -  
36 - /**  
37 - * 消息转发配置  
38 - */  
39 - /*  
40 - * @Data  
41 - * public static class ForwardMessage {  
42 - *  
43 - * /**  
44 - * 是否转发所有设备消息到 EMQX  
45 - * <p>  
46 - * 默认为 true 开启  
47 - */  
48 - // private boolean forwardAllDeviceMessageToEmqx = true;  
49 -  
50 - /**  
51 - * 是否转发所有设备消息到 HTTP  
52 - * <p>  
53 - * 默认为 false 关闭  
54 - */  
55 - // private boolean forwardAllDeviceMessageToHttp = false;  
56 - // }  
57 -  
58 } 24 }
59 \ No newline at end of file 25 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/downstream/IotDeviceDownstreamHandler.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.core.downstream;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
5 -  
6 -/**  
7 - * IoT 设备下行处理器  
8 - * <p>  
9 - * 目的:每个 plugin 需要实现,用于处理 server 下行的指令(请求),从而实现从 server => plugin => device 的下行流程  
10 - *  
11 - * @author 芋道源码  
12 - */  
13 -public interface IotDeviceDownstreamHandler {  
14 -  
15 - /**  
16 - * 调用设备服务  
17 - *  
18 - * @param invokeReqDTO 调用设备服务的请求  
19 - * @return 是否成功  
20 - */  
21 - CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO);  
22 -  
23 - /**  
24 - * 获取设备属性  
25 - *  
26 - * @param getReqDTO 获取设备属性的请求  
27 - * @return 是否成功  
28 - */  
29 - CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO);  
30 -  
31 - /**  
32 - * 设置设备属性  
33 - *  
34 - * @param setReqDTO 设置设备属性的请求  
35 - * @return 是否成功  
36 - */  
37 - CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO);  
38 -  
39 - /**  
40 - * 设置设备配置  
41 - *  
42 - * @param setReqDTO 设置设备配置的请求  
43 - * @return 是否成功  
44 - */  
45 - CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO);  
46 -  
47 - /**  
48 - * 升级设备 OTA  
49 - *  
50 - * @param upgradeReqDTO 升级设备 OTA 的请求  
51 - * @return 是否成功  
52 - */  
53 - CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO);  
54 -  
55 -}  
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/downstream/IotDeviceDownstreamServer.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.core.downstream;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
5 -import cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonProperties;  
6 -import lombok.RequiredArgsConstructor;  
7 -import lombok.extern.slf4j.Slf4j;  
8 -  
9 -/**  
10 - * IoT 设备下行服务,直接转发给 device 设备  
11 - *  
12 - * @author 芋道源码  
13 - */  
14 -@Slf4j  
15 -@RequiredArgsConstructor  
16 -public class IotDeviceDownstreamServer {  
17 -  
18 - private final IotNetComponentCommonProperties properties;  
19 - private final IotDeviceDownstreamHandler deviceDownstreamHandler;  
20 -  
21 - /**  
22 - * 调用设备服务  
23 - *  
24 - * @param invokeReqDTO 调用设备服务的请求  
25 - * @return 是否成功  
26 - */  
27 - public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) {  
28 - return deviceDownstreamHandler.invokeDeviceService(invokeReqDTO);  
29 - }  
30 -  
31 - /**  
32 - * 获取设备属性  
33 - *  
34 - * @param getReqDTO 获取设备属性的请求  
35 - * @return 是否成功  
36 - */  
37 - public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {  
38 - return deviceDownstreamHandler.getDeviceProperty(getReqDTO);  
39 - }  
40 -  
41 - /**  
42 - * 设置设备属性  
43 - *  
44 - * @param setReqDTO 设置设备属性的请求  
45 - * @return 是否成功  
46 - */  
47 - public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) {  
48 - return deviceDownstreamHandler.setDeviceProperty(setReqDTO);  
49 - }  
50 -  
51 - /**  
52 - * 设置设备配置  
53 - *  
54 - * @param setReqDTO 设置设备配置的请求  
55 - * @return 是否成功  
56 - */  
57 - public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {  
58 - return deviceDownstreamHandler.setDeviceConfig(setReqDTO);  
59 - }  
60 -  
61 - /**  
62 - * 升级设备 OTA  
63 - *  
64 - * @param upgradeReqDTO 升级设备 OTA 的请求  
65 - * @return 是否成功  
66 - */  
67 - public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {  
68 - return deviceDownstreamHandler.upgradeDeviceOta(upgradeReqDTO);  
69 - }  
70 -  
71 - /**  
72 - * 获得内部组件标识  
73 - *  
74 - * @return 组件标识  
75 - */  
76 - public String getComponentId() {  
77 - return properties.getPluginKey();  
78 - }  
79 -  
80 -}  
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/heartbeat/IotNetComponentInstanceHeartbeatJob.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.core.heartbeat;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.system.SystemUtil;  
5 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
6 -import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;  
7 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;  
8 -import cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonProperties;  
9 -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry.IotNetComponentInfo;  
10 -import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils;  
11 -import lombok.RequiredArgsConstructor;  
12 -import lombok.extern.slf4j.Slf4j;  
13 -import org.springframework.scheduling.annotation.Scheduled;  
14 -  
15 -import java.util.Collection;  
16 -import java.util.concurrent.TimeUnit;  
17 -  
18 -/**  
19 - * IoT 网络组件实例心跳定时任务  
20 - * <p>  
21 - * 将组件的状态,定时上报给 server 服务器  
22 - *  
23 - * @author haohao  
24 - */  
25 -@RequiredArgsConstructor  
26 -@Slf4j  
27 -public class IotNetComponentInstanceHeartbeatJob {  
28 -  
29 - private final IotDeviceUpstreamApi deviceUpstreamApi;  
30 - private final IotNetComponentCommonProperties commonProperties;  
31 - private final IotNetComponentRegistry componentRegistry;  
32 -  
33 - /**  
34 - * 初始化方法,由 Spring 调用:注册当前组件并发送上线心跳  
35 - */  
36 - public void init() {  
37 - // 发送所有组件的上线心跳  
38 - Collection<IotNetComponentInfo> components = componentRegistry.getAllComponents();  
39 - if (CollUtil.isEmpty(components)) {  
40 - return;  
41 - }  
42 - for (IotNetComponentInfo component : components) {  
43 - try {  
44 - CommonResult<Boolean> result = deviceUpstreamApi.heartbeatPluginInstance(  
45 - buildPluginInstanceHeartbeatReqDTO(component, true));  
46 - log.info("[init][组件({})上线结果:{}]", component.getPluginKey(), result);  
47 - } catch (Exception e) {  
48 - log.error("[init][组件({})上线发送异常]", component.getPluginKey(), e);  
49 - }  
50 - }  
51 - }  
52 -  
53 - /**  
54 - * 停止方法,由 Spring 调用:发送下线心跳并注销组件  
55 - */  
56 - public void stop() {  
57 - // 发送所有组件的下线心跳  
58 - Collection<IotNetComponentInfo> components = componentRegistry.getAllComponents();  
59 - if (CollUtil.isEmpty(components)) {  
60 - return;  
61 - }  
62 - for (IotNetComponentInfo component : components) {  
63 - try {  
64 - CommonResult<Boolean> result = deviceUpstreamApi.heartbeatPluginInstance(  
65 - buildPluginInstanceHeartbeatReqDTO(component, false));  
66 - log.info("[stop][组件({})下线结果:{}]", component.getPluginKey(), result);  
67 - } catch (Exception e) {  
68 - log.error("[stop][组件({})下线发送异常]", component.getPluginKey(), e);  
69 - }  
70 - }  
71 -  
72 - // 注销当前组件  
73 - componentRegistry.unregisterComponent(commonProperties.getPluginKey());  
74 - }  
75 -  
76 - /**  
77 - * 定时发送心跳  
78 - */  
79 - @Scheduled(initialDelay = 1, fixedRate = 1, timeUnit = TimeUnit.MINUTES) // 1 分钟执行一次  
80 - public void execute() {  
81 - // 发送所有组件的心跳  
82 - Collection<IotNetComponentInfo> components = componentRegistry.getAllComponents();  
83 - if (CollUtil.isEmpty(components)) {  
84 - return;  
85 - }  
86 - for (IotNetComponentInfo component : components) {  
87 - try {  
88 - CommonResult<Boolean> result = deviceUpstreamApi.heartbeatPluginInstance(  
89 - buildPluginInstanceHeartbeatReqDTO(component, true));  
90 - log.info("[execute][组件({})心跳结果:{}]", component.getPluginKey(), result);  
91 - } catch (Exception e) {  
92 - log.error("[execute][组件({})心跳发送异常]", component.getPluginKey(), e);  
93 - }  
94 - }  
95 - }  
96 -  
97 - /**  
98 - * 构建心跳 DTO  
99 - *  
100 - * @param component 组件信息  
101 - * @param online 是否在线  
102 - * @return 心跳 DTO  
103 - */  
104 - private IotPluginInstanceHeartbeatReqDTO buildPluginInstanceHeartbeatReqDTO(IotNetComponentInfo component,  
105 - Boolean online) {  
106 - return new IotPluginInstanceHeartbeatReqDTO()  
107 - .setPluginKey(component.getPluginKey()).setProcessId(component.getProcessId())  
108 - .setHostIp(component.getHostIp()).setDownstreamPort(component.getDownstreamPort())  
109 - .setOnline(online);  
110 - }  
111 -}  
112 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/heartbeat/IotNetComponentRegistry.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.core.heartbeat;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.map.MapUtil;  
5 -import lombok.Data;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -import org.springframework.stereotype.Component;  
8 -  
9 -import java.util.Collection;  
10 -import java.util.Map;  
11 -import java.util.concurrent.ConcurrentHashMap;  
12 -  
13 -/**  
14 - * IoT 网络组件注册表  
15 - * <p>  
16 - * 用于管理多个网络组件的注册信息,解决多组件心跳问题  
17 - *  
18 - * @author haohao  
19 - */  
20 -@Component  
21 -@Slf4j  
22 -public class IotNetComponentRegistry {  
23 -  
24 - /**  
25 - * 网络组件信息  
26 - */  
27 - @Data  
28 - public static class IotNetComponentInfo {  
29 -  
30 - /**  
31 - * 组件 Key  
32 - */  
33 - private final String pluginKey;  
34 -  
35 - /**  
36 - * 主机 IP  
37 - */  
38 - private final String hostIp;  
39 -  
40 - /**  
41 - * 下游端口  
42 - */  
43 - private final Integer downstreamPort;  
44 -  
45 - /**  
46 - * 进程 ID  
47 - */  
48 - private final String processId;  
49 - }  
50 -  
51 - /**  
52 - * 组件映射表:key 为组件 Key  
53 - */  
54 - private final Map<String, IotNetComponentInfo> components = new ConcurrentHashMap<>();  
55 -  
56 - /**  
57 - * 注册网络组件  
58 - *  
59 - * @param pluginKey 组件 Key  
60 - * @param hostIp 主机 IP  
61 - * @param downstreamPort 下游端口  
62 - * @param processId 进程 ID  
63 - */  
64 - public void registerComponent(String pluginKey, String hostIp, Integer downstreamPort, String processId) {  
65 - log.info("[registerComponent][注册网络组件, pluginKey={}, hostIp={}, downstreamPort={}, processId={}]",  
66 - pluginKey, hostIp, downstreamPort, processId);  
67 - components.put(pluginKey, new IotNetComponentInfo(pluginKey, hostIp, downstreamPort, processId));  
68 - }  
69 -  
70 - /**  
71 - * 注销网络组件  
72 - *  
73 - * @param pluginKey 组件 Key  
74 - */  
75 - public void unregisterComponent(String pluginKey) {  
76 - log.info("[unregisterComponent][注销网络组件, pluginKey={}]", pluginKey);  
77 - components.remove(pluginKey);  
78 - }  
79 -  
80 - /**  
81 - * 获取所有网络组件  
82 - *  
83 - * @return 所有组件集合  
84 - */  
85 - public Collection<IotNetComponentInfo> getAllComponents() {  
86 - return CollUtil.isEmpty(components) ? CollUtil.newArrayList() : components.values();  
87 - }  
88 -  
89 - /**  
90 - * 获取指定网络组件  
91 - *  
92 - * @param pluginKey 组件 Key  
93 - * @return 组件信息  
94 - */  
95 - public IotNetComponentInfo getComponent(String pluginKey) {  
96 - return MapUtil.isEmpty(components) ? null : components.get(pluginKey);  
97 - }  
98 -}  
99 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/upstream/IotDeviceUpstreamClient.java
@@ -53,8 +53,4 @@ public class IotDeviceUpstreamClient implements IotDeviceUpstreamApi { @@ -53,8 +53,4 @@ public class IotDeviceUpstreamClient implements IotDeviceUpstreamApi {
53 return deviceUpstreamApi.reportDeviceProperty(reportReqDTO); 53 return deviceUpstreamApi.reportDeviceProperty(reportReqDTO);
54 } 54 }
55 55
56 - @Override  
57 - public CommonResult<Boolean> heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {  
58 - return deviceUpstreamApi.heartbeatPluginInstance(heartbeatReqDTO);  
59 - }  
60 } 56 }
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/resources/META-INF/spring.factories deleted
1 -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  
2 - cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonAutoConfiguration  
3 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-emqx/src/main/java/cn/iocoder/yudao/module/iot/net/component/emqx/config/IotNetComponentEmqxAutoConfiguration.java
@@ -2,13 +2,7 @@ package cn.iocoder.yudao.module.iot.net.component.emqx.config; @@ -2,13 +2,7 @@ package cn.iocoder.yudao.module.iot.net.component.emqx.config;
2 2
3 import cn.hutool.core.util.IdUtil; 3 import cn.hutool.core.util.IdUtil;
4 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
5 -import cn.hutool.system.SystemUtil;  
6 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; 5 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
7 -import cn.iocoder.yudao.module.iot.net.component.core.config.IotNetComponentCommonProperties;  
8 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
9 -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry;  
10 -import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils;  
11 -import cn.iocoder.yudao.module.iot.net.component.emqx.downstream.IotDeviceDownstreamHandlerImpl;  
12 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.IotDeviceUpstreamServer; 6 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.IotDeviceUpstreamServer;
13 import io.vertx.core.Vertx; 7 import io.vertx.core.Vertx;
14 import io.vertx.mqtt.MqttClient; 8 import io.vertx.mqtt.MqttClient;
@@ -38,16 +32,6 @@ import org.springframework.context.event.EventListener; @@ -38,16 +32,6 @@ import org.springframework.context.event.EventListener;
38 public class IotNetComponentEmqxAutoConfiguration { 32 public class IotNetComponentEmqxAutoConfiguration {
39 33
40 /** 34 /**
41 - * 组件 key  
42 - */  
43 - private static final String PLUGIN_KEY = "emqx";  
44 -  
45 - // TODO @haohao:这个是不是要去掉哈。  
46 - public IotNetComponentEmqxAutoConfiguration() {  
47 - // 构造函数中不输出日志,移到 initialize 方法中  
48 - }  
49 -  
50 - /**  
51 * 初始化 EMQX 组件 35 * 初始化 EMQX 组件
52 * 36 *
53 * @param event 应用启动事件 37 * @param event 应用启动事件
@@ -57,21 +41,7 @@ public class IotNetComponentEmqxAutoConfiguration { @@ -57,21 +41,7 @@ public class IotNetComponentEmqxAutoConfiguration {
57 log.info("[IotNetComponentEmqxAutoConfiguration][开始初始化]"); 41 log.info("[IotNetComponentEmqxAutoConfiguration][开始初始化]");
58 42
59 // 从应用上下文中获取需要的 Bean 43 // 从应用上下文中获取需要的 Bean
60 - IotNetComponentRegistry componentRegistry = event.getApplicationContext()  
61 - .getBean(IotNetComponentRegistry.class);  
62 - IotNetComponentCommonProperties commonProperties = event.getApplicationContext()  
63 - .getBean(IotNetComponentCommonProperties.class);  
64 -  
65 - // 设置当前组件的核心标识  
66 - // 注意:这里只为当前 EMQX 组件设置 pluginKey,不影响其他组件  
67 - commonProperties.setPluginKey(PLUGIN_KEY);  
68 -  
69 - // 将 EMQX 组件注册到组件注册表  
70 - componentRegistry.registerComponent(  
71 - PLUGIN_KEY,  
72 - SystemUtil.getHostInfo().getAddress(),  
73 - 0, // 内嵌模式固定为 0  
74 - IotNetComponentCommonUtils.getProcessId()); 44 + // TODO @芋艿:看看要不要监听下
75 45
76 log.info("[initialize][IoT EMQX 组件初始化完成]"); 46 log.info("[initialize][IoT EMQX 组件初始化完成]");
77 } 47 }
@@ -89,15 +59,6 @@ public class IotNetComponentEmqxAutoConfiguration { @@ -89,15 +59,6 @@ public class IotNetComponentEmqxAutoConfiguration {
89 */ 59 */
90 @Bean 60 @Bean
91 public MqttClient mqttClient(@Qualifier("emqxVertx") Vertx vertx, IotNetComponentEmqxProperties emqxProperties) { 61 public MqttClient mqttClient(@Qualifier("emqxVertx") Vertx vertx, IotNetComponentEmqxProperties emqxProperties) {
92 - // 使用 debug 级别记录详细配置,减少生产环境日志  
93 - if (log.isDebugEnabled()) {  
94 - log.debug("MQTT 配置: host={}, port={}, username={}, ssl={}",  
95 - emqxProperties.getMqttHost(), emqxProperties.getMqttPort(),  
96 - emqxProperties.getMqttUsername(), emqxProperties.getMqttSsl());  
97 - } else {  
98 - log.info("MQTT 连接至: {}:{}", emqxProperties.getMqttHost(), emqxProperties.getMqttPort());  
99 - }  
100 -  
101 MqttClientOptions options = new MqttClientOptions() 62 MqttClientOptions options = new MqttClientOptions()
102 .setClientId("yudao-iot-downstream-" + IdUtil.fastSimpleUUID()) 63 .setClientId("yudao-iot-downstream-" + IdUtil.fastSimpleUUID())
103 .setUsername(emqxProperties.getMqttUsername()) 64 .setUsername(emqxProperties.getMqttUsername())
@@ -115,16 +76,8 @@ public class IotNetComponentEmqxAutoConfiguration { @@ -115,16 +76,8 @@ public class IotNetComponentEmqxAutoConfiguration {
115 IotDeviceUpstreamApi deviceUpstreamApi, 76 IotDeviceUpstreamApi deviceUpstreamApi,
116 IotNetComponentEmqxProperties emqxProperties, 77 IotNetComponentEmqxProperties emqxProperties,
117 @Qualifier("emqxVertx") Vertx vertx, 78 @Qualifier("emqxVertx") Vertx vertx,
118 - MqttClient mqttClient,  
119 - IotNetComponentRegistry componentRegistry) {  
120 - return new IotDeviceUpstreamServer(emqxProperties, deviceUpstreamApi, vertx, mqttClient, componentRegistry); 79 + MqttClient mqttClient) {
  80 + return new IotDeviceUpstreamServer(emqxProperties, deviceUpstreamApi, vertx, mqttClient);
121 } 81 }
122 82
123 - /**  
124 - * 创建设备下行处理器  
125 - */  
126 - @Bean(name = "emqxDeviceDownstreamHandler")  
127 - public IotDeviceDownstreamHandler deviceDownstreamHandler(MqttClient mqttClient) {  
128 - return new IotDeviceDownstreamHandlerImpl(mqttClient);  
129 - }  
130 } 83 }
131 \ No newline at end of file 84 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-emqx/src/main/java/cn/iocoder/yudao/module/iot/net/component/emqx/downstream/IotDeviceDownstreamHandlerImpl.java
1 package cn.iocoder.yudao.module.iot.net.component.emqx.downstream; 1 package cn.iocoder.yudao.module.iot.net.component.emqx.downstream;
2 2
3 -import cn.hutool.core.util.StrUtil;  
4 -import cn.hutool.json.JSONObject;  
5 -import cn.hutool.json.JSONUtil;  
6 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
7 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
8 -import cn.iocoder.yudao.module.iot.net.component.core.constants.IotDeviceTopicEnum;  
9 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
10 -import cn.iocoder.yudao.module.iot.net.component.core.message.IotMqttMessage;  
11 -import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils;  
12 -import io.netty.handler.codec.mqtt.MqttQoS;  
13 -import io.vertx.core.buffer.Buffer;  
14 -import io.vertx.mqtt.MqttClient;  
15 -import lombok.extern.slf4j.Slf4j;  
16 -  
17 -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.MQTT_TOPIC_ILLEGAL;  
18 -  
19 -/**  
20 - * EMQX 网络组件的 {@link IotDeviceDownstreamHandler} 实现类  
21 - *  
22 - * @author 芋道源码  
23 - */  
24 -@Slf4j  
25 -public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandler {  
26 -  
27 - /**  
28 - * MQTT 客户端  
29 - */  
30 - private final MqttClient mqttClient;  
31 -  
32 - /**  
33 - * 构造函数  
34 - *  
35 - * @param mqttClient MQTT 客户端  
36 - */  
37 - public IotDeviceDownstreamHandlerImpl(MqttClient mqttClient) {  
38 - this.mqttClient = mqttClient;  
39 - }  
40 -  
41 - @Override  
42 - public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO reqDTO) {  
43 - log.info("[invokeService][开始调用设备服务][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));  
44 -  
45 - // 验证参数  
46 - if (reqDTO.getProductKey() == null || reqDTO.getDeviceName() == null || reqDTO.getIdentifier() == null) {  
47 - log.error("[invokeService][参数不完整][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));  
48 - return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());  
49 - }  
50 -  
51 - try {  
52 - // 构建请求主题  
53 - String topic = IotDeviceTopicEnum.buildServiceTopic(reqDTO.getProductKey(), reqDTO.getDeviceName(),  
54 - reqDTO.getIdentifier());  
55 -  
56 - // 构建请求消息  
57 - String requestId = StrUtil.isNotEmpty(reqDTO.getRequestId()) ? reqDTO.getRequestId()  
58 - : IotNetComponentCommonUtils.generateRequestId();  
59 - IotMqttMessage message = IotMqttMessage.createServiceInvokeMessage(  
60 - requestId, reqDTO.getIdentifier(), reqDTO.getParams());  
61 -  
62 - // 发送消息  
63 - publishMessage(topic, message.toJsonObject());  
64 -  
65 - log.info("[invokeService][调用设备服务成功][requestId: {}][topic: {}]", requestId, topic);  
66 - return CommonResult.success(true);  
67 - } catch (Exception e) {  
68 - log.error("[invokeService][调用设备服务异常][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO), e);  
69 - return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());  
70 - }  
71 - }  
72 -  
73 - @Override  
74 - public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {  
75 - // 暂未实现,返回成功  
76 - return CommonResult.success(true);  
77 - }  
78 -  
79 - @Override  
80 - public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO reqDTO) {  
81 - log.info("[setProperty][开始设置设备属性][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));  
82 -  
83 - // 验证参数  
84 - if (reqDTO.getProductKey() == null || reqDTO.getDeviceName() == null) {  
85 - log.error("[setProperty][参数不完整][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));  
86 - return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());  
87 - }  
88 -  
89 - try {  
90 - // 构建请求主题  
91 - String topic = IotDeviceTopicEnum.buildPropertySetTopic(reqDTO.getProductKey(), reqDTO.getDeviceName());  
92 -  
93 - // 构建请求消息  
94 - String requestId = StrUtil.isNotEmpty(reqDTO.getRequestId()) ? reqDTO.getRequestId()  
95 - : IotNetComponentCommonUtils.generateRequestId();  
96 - IotMqttMessage message = IotMqttMessage.createPropertySetMessage(requestId, reqDTO.getProperties());  
97 -  
98 - // 发送消息  
99 - publishMessage(topic, message.toJsonObject());  
100 -  
101 - log.info("[setProperty][设置设备属性成功][requestId: {}][topic: {}]", requestId, topic);  
102 - return CommonResult.success(true);  
103 - } catch (Exception e) {  
104 - log.error("[setProperty][设置设备属性异常][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO), e);  
105 - return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());  
106 - }  
107 - }  
108 -  
109 - @Override  
110 - public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {  
111 - // 暂未实现,返回成功  
112 - return CommonResult.success(true);  
113 - }  
114 -  
115 - @Override  
116 - public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {  
117 - // 暂未实现,返回成功  
118 - return CommonResult.success(true);  
119 - }  
120 -  
121 - /**  
122 - * 发布 MQTT 消息  
123 - *  
124 - * @param topic 主题  
125 - * @param payload 消息内容  
126 - */  
127 - private void publishMessage(String topic, JSONObject payload) {  
128 - mqttClient.publish(  
129 - topic,  
130 - Buffer.buffer(payload.toString()),  
131 - MqttQoS.AT_LEAST_ONCE,  
132 - false,  
133 - false);  
134 - log.info("[publishMessage][发送消息成功][topic: {}][payload: {}]", topic, payload);  
135 - }  
136 -}  
137 \ No newline at end of file 3 \ No newline at end of file
  4 +// TODO @芋艿:后续再支持下;@haohao;改成消费者
  5 +///**
  6 +// * EMQX 网络组件的 {@link IotDeviceDownstreamHandler} 实现类
  7 +// *
  8 +// * @author 芋道源码
  9 +// */
  10 +//@Slf4j
  11 +//public class IotDeviceDownstreamHandlerImpl {
  12 +//
  13 +// /**
  14 +// * MQTT 客户端
  15 +// */
  16 +// private final MqttClient mqttClient;
  17 +//
  18 +// /**
  19 +// * 构造函数
  20 +// *
  21 +// * @param mqttClient MQTT 客户端
  22 +// */
  23 +// public IotDeviceDownstreamHandlerImpl(MqttClient mqttClient) {
  24 +// this.mqttClient = mqttClient;
  25 +// }
  26 +//
  27 +// @Override
  28 +// public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO reqDTO) {
  29 +// log.info("[invokeService][开始调用设备服务][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));
  30 +//
  31 +// // 验证参数
  32 +// if (reqDTO.getProductKey() == null || reqDTO.getDeviceName() == null || reqDTO.getIdentifier() == null) {
  33 +// log.error("[invokeService][参数不完整][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));
  34 +// return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());
  35 +// }
  36 +//
  37 +// try {
  38 +// // 构建请求主题
  39 +// String topic = IotDeviceTopicEnum.buildServiceTopic(reqDTO.getProductKey(), reqDTO.getDeviceName(),
  40 +// reqDTO.getIdentifier());
  41 +//
  42 +// // 构建请求消息
  43 +// String requestId = StrUtil.isNotEmpty(reqDTO.getRequestId()) ? reqDTO.getRequestId()
  44 +// : IotNetComponentCommonUtils.generateRequestId();
  45 +// IotMqttMessage message = IotMqttMessage.createServiceInvokeMessage(
  46 +// requestId, reqDTO.getIdentifier(), reqDTO.getParams());
  47 +//
  48 +// // 发送消息
  49 +// publishMessage(topic, message.toJsonObject());
  50 +//
  51 +// log.info("[invokeService][调用设备服务成功][requestId: {}][topic: {}]", requestId, topic);
  52 +// return CommonResult.success(true);
  53 +// } catch (Exception e) {
  54 +// log.error("[invokeService][调用设备服务异常][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO), e);
  55 +// return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());
  56 +// }
  57 +// }
  58 +//
  59 +// @Override
  60 +// public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {
  61 +// // 暂未实现,返回成功
  62 +// return CommonResult.success(true);
  63 +// }
  64 +//
  65 +// @Override
  66 +// public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO reqDTO) {
  67 +// log.info("[setProperty][开始设置设备属性][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));
  68 +//
  69 +// // 验证参数
  70 +// if (reqDTO.getProductKey() == null || reqDTO.getDeviceName() == null) {
  71 +// log.error("[setProperty][参数不完整][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO));
  72 +// return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());
  73 +// }
  74 +//
  75 +// try {
  76 +// // 构建请求主题
  77 +// String topic = IotDeviceTopicEnum.buildPropertySetTopic(reqDTO.getProductKey(), reqDTO.getDeviceName());
  78 +//
  79 +// // 构建请求消息
  80 +// String requestId = StrUtil.isNotEmpty(reqDTO.getRequestId()) ? reqDTO.getRequestId()
  81 +// : IotNetComponentCommonUtils.generateRequestId();
  82 +// IotMqttMessage message = IotMqttMessage.createPropertySetMessage(requestId, reqDTO.getProperties());
  83 +//
  84 +// // 发送消息
  85 +// publishMessage(topic, message.toJsonObject());
  86 +//
  87 +// log.info("[setProperty][设置设备属性成功][requestId: {}][topic: {}]", requestId, topic);
  88 +// return CommonResult.success(true);
  89 +// } catch (Exception e) {
  90 +// log.error("[setProperty][设置设备属性异常][reqDTO: {}]", JSONUtil.toJsonStr(reqDTO), e);
  91 +// return CommonResult.error(MQTT_TOPIC_ILLEGAL.getCode(), MQTT_TOPIC_ILLEGAL.getMsg());
  92 +// }
  93 +// }
  94 +//
  95 +// @Override
  96 +// public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {
  97 +// // 暂未实现,返回成功
  98 +// return CommonResult.success(true);
  99 +// }
  100 +//
  101 +// @Override
  102 +// public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {
  103 +// // 暂未实现,返回成功
  104 +// return CommonResult.success(true);
  105 +// }
  106 +//
  107 +// /**
  108 +// * 发布 MQTT 消息
  109 +// *
  110 +// * @param topic 主题
  111 +// * @param payload 消息内容
  112 +// */
  113 +// private void publishMessage(String topic, JSONObject payload) {
  114 +// mqttClient.publish(
  115 +// topic,
  116 +// Buffer.buffer(payload.toString()),
  117 +// MqttQoS.AT_LEAST_ONCE,
  118 +// false,
  119 +// false);
  120 +// log.info("[publishMessage][发送消息成功][topic: {}][payload: {}]", topic, payload);
  121 +// }
  122 +//}
138 \ No newline at end of file 123 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-emqx/src/main/java/cn/iocoder/yudao/module/iot/net/component/emqx/upstream/IotDeviceUpstreamServer.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.iot.net.component.emqx.upstream; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.iot.net.component.emqx.upstream;
3 import cn.hutool.core.util.ArrayUtil; 3 import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; 5 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
6 -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry;  
7 import cn.iocoder.yudao.module.iot.net.component.emqx.config.IotNetComponentEmqxProperties; 6 import cn.iocoder.yudao.module.iot.net.component.emqx.config.IotNetComponentEmqxProperties;
8 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceAuthVertxHandler; 7 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceAuthVertxHandler;
9 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceMqttMessageHandler; 8 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceMqttMessageHandler;
@@ -40,7 +39,6 @@ public class IotDeviceUpstreamServer { @@ -40,7 +39,6 @@ public class IotDeviceUpstreamServer {
40 private final MqttClient client; 39 private final MqttClient client;
41 private final IotNetComponentEmqxProperties emqxProperties; 40 private final IotNetComponentEmqxProperties emqxProperties;
42 private final IotDeviceMqttMessageHandler mqttMessageHandler; 41 private final IotDeviceMqttMessageHandler mqttMessageHandler;
43 - private final IotNetComponentRegistry componentRegistry;  
44 42
45 /** 43 /**
46 * 服务运行状态标志 44 * 服务运行状态标志
@@ -50,12 +48,10 @@ public class IotDeviceUpstreamServer { @@ -50,12 +48,10 @@ public class IotDeviceUpstreamServer {
50 public IotDeviceUpstreamServer(IotNetComponentEmqxProperties emqxProperties, 48 public IotDeviceUpstreamServer(IotNetComponentEmqxProperties emqxProperties,
51 IotDeviceUpstreamApi deviceUpstreamApi, 49 IotDeviceUpstreamApi deviceUpstreamApi,
52 Vertx vertx, 50 Vertx vertx,
53 - MqttClient client,  
54 - IotNetComponentRegistry componentRegistry) { 51 + MqttClient client) {
55 this.vertx = vertx; 52 this.vertx = vertx;
56 this.emqxProperties = emqxProperties; 53 this.emqxProperties = emqxProperties;
57 this.client = client; 54 this.client = client;
58 - this.componentRegistry = componentRegistry;  
59 55
60 // 创建 Router 实例 56 // 创建 Router 实例
61 Router router = Router.router(vertx); 57 Router router = Router.router(vertx);
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
@@ -5,8 +5,6 @@ import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; @@ -5,8 +5,6 @@ import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
5 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBusSubscriber; 5 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBusSubscriber;
6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; 7 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
8 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
9 -import cn.iocoder.yudao.module.iot.net.component.http.downstream.IotDeviceDownstreamHandlerImpl;  
10 import cn.iocoder.yudao.module.iot.net.component.http.upstream.IotDeviceUpstreamServer; 8 import cn.iocoder.yudao.module.iot.net.component.http.upstream.IotDeviceUpstreamServer;
11 import io.vertx.core.Vertx; 9 import io.vertx.core.Vertx;
12 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
@@ -89,14 +87,4 @@ public class IotNetComponentHttpAutoConfiguration { @@ -89,14 +87,4 @@ public class IotNetComponentHttpAutoConfiguration {
89 return new IotDeviceUpstreamServer(vertx, properties, deviceUpstreamApi, deviceMessageProducer); 87 return new IotDeviceUpstreamServer(vertx, properties, deviceUpstreamApi, deviceMessageProducer);
90 } 88 }
91 89
92 - /**  
93 - * 创建设备下行处理器  
94 - *  
95 - * @return 设备下行处理器  
96 - */  
97 - @Bean(name = "httpDeviceDownstreamHandler")  
98 - public IotDeviceDownstreamHandler deviceDownstreamHandler() {  
99 - return new IotDeviceDownstreamHandlerImpl();  
100 - }  
101 -  
102 } 90 }
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/downstream/IotDeviceDownstreamHandlerImpl.java
1 package cn.iocoder.yudao.module.iot.net.component.http.downstream; 1 package cn.iocoder.yudao.module.iot.net.component.http.downstream;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
5 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -  
8 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.NOT_IMPLEMENTED;  
9 -  
10 -/**  
11 - * HTTP 网络组件的 {@link IotDeviceDownstreamHandler} 实现类  
12 - * <p>  
13 - * 但是:由于设备通过 HTTP 短链接接入,导致其实无法下行指导给 device 设备,所以基本都是直接返回失败!!!  
14 - * 类似 MQTT、WebSocket、TCP 网络组件,是可以实现下行指令的。  
15 - *  
16 - * @author 芋道源码  
17 - */  
18 -@Slf4j  
19 -public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandler {  
20 -  
21 - /**  
22 - * 不支持的错误消息  
23 - */  
24 - private static final String NOT_SUPPORTED_MSG = "HTTP 不支持设备下行通信";  
25 -  
26 - @Override  
27 - public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) {  
28 - return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);  
29 - }  
30 -  
31 - @Override  
32 - public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {  
33 - return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);  
34 - }  
35 -  
36 - @Override  
37 - public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) {  
38 - return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);  
39 - }  
40 -  
41 - @Override  
42 - public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {  
43 - return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);  
44 - }  
45 -  
46 - @Override  
47 - public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {  
48 - return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);  
49 - }  
50 -} 3 +// TODO @芋艿:实现下;
  4 +///**
  5 +// * HTTP 网络组件的 {@link IotDeviceDownstreamHandler} 实现类
  6 +// * <p>
  7 +// * 但是:由于设备通过 HTTP 短链接接入,导致其实无法下行指导给 device 设备,所以基本都是直接返回失败!!!
  8 +// * 类似 MQTT、WebSocket、TCP 网络组件,是可以实现下行指令的。
  9 +// *
  10 +// * @author 芋道源码
  11 +// */
  12 +//@Slf4j
  13 +//public class IotDeviceDownstreamHandlerImpl implements IotDeviceDownstreamHandler {
  14 +//
  15 +// /**
  16 +// * 不支持的错误消息
  17 +// */
  18 +// private static final String NOT_SUPPORTED_MSG = "HTTP 不支持设备下行通信";
  19 +//
  20 +// @Override
  21 +// public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) {
  22 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);
  23 +// }
  24 +//
  25 +// @Override
  26 +// public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {
  27 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);
  28 +// }
  29 +//
  30 +// @Override
  31 +// public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) {
  32 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);
  33 +// }
  34 +//
  35 +// @Override
  36 +// public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {
  37 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);
  38 +// }
  39 +//
  40 +// @Override
  41 +// public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {
  42 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(), NOT_SUPPORTED_MSG);
  43 +// }
  44 +//}
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/config/IotNetComponentServerConfiguration.java
1 package cn.iocoder.yudao.module.iot.net.component.server.config; 1 package cn.iocoder.yudao.module.iot.net.component.server.config;
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.net.component.core.downstream.IotDeviceDownstreamHandler;  
5 -import cn.iocoder.yudao.module.iot.net.component.server.downstream.IotComponentDownstreamHandlerImpl;  
6 -import cn.iocoder.yudao.module.iot.net.component.server.downstream.IotComponentDownstreamServer;  
7 -import cn.iocoder.yudao.module.iot.net.component.server.heartbeat.IotComponentHeartbeatJob;  
8 import cn.iocoder.yudao.module.iot.net.component.server.upstream.IotComponentUpstreamClient; 4 import cn.iocoder.yudao.module.iot.net.component.server.upstream.IotComponentUpstreamClient;
9 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10 import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -55,45 +51,6 @@ public class IotNetComponentServerConfiguration { @@ -55,45 +51,6 @@ public class IotNetComponentServerConfiguration {
55 } 51 }
56 52
57 /** 53 /**
58 - * 配置设备下行处理器  
59 - *  
60 - * @return 下行处理器  
61 - */  
62 - @Bean  
63 - @Primary  
64 - public IotDeviceDownstreamHandler deviceDownstreamHandler() {  
65 - return new IotComponentDownstreamHandlerImpl();  
66 - }  
67 -  
68 - /**  
69 - * 配置下行服务器  
70 - *  
71 - * @param properties 配置  
72 - * @param downstreamHandler 下行处理器  
73 - * @return 下行服务器  
74 - */  
75 - @Bean(initMethod = "start", destroyMethod = "stop")  
76 - public IotComponentDownstreamServer deviceDownstreamServer(IotNetComponentServerProperties properties,  
77 - @org.springframework.beans.factory.annotation.Qualifier("deviceDownstreamHandler") IotDeviceDownstreamHandler downstreamHandler) {  
78 - return new IotComponentDownstreamServer(properties, downstreamHandler);  
79 - }  
80 -  
81 - /**  
82 - * 配置心跳任务  
83 - *  
84 - * @param deviceUpstreamApi 上行接口  
85 - * @param downstreamServer 下行服务器  
86 - * @param properties 配置  
87 - * @return 心跳任务  
88 - */  
89 - @Bean(initMethod = "init", destroyMethod = "stop")  
90 - public IotComponentHeartbeatJob heartbeatJob(IotDeviceUpstreamApi deviceUpstreamApi,  
91 - IotComponentDownstreamServer downstreamServer,  
92 - IotNetComponentServerProperties properties) {  
93 - return new IotComponentHeartbeatJob(deviceUpstreamApi, downstreamServer, properties);  
94 - }  
95 -  
96 - /**  
97 * 配置默认的设备上行客户端,避免在独立运行模式下的循环依赖问题 54 * 配置默认的设备上行客户端,避免在独立运行模式下的循环依赖问题
98 * 55 *
99 * @return 设备上行客户端 56 * @return 设备上行客户端
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/config/IotNetComponentServerProperties.java
@@ -47,10 +47,4 @@ public class IotNetComponentServerProperties { @@ -47,10 +47,4 @@ public class IotNetComponentServerProperties {
47 */ 47 */
48 private String serverKey = "yudao-module-iot-net-component-server"; 48 private String serverKey = "yudao-module-iot-net-component-server";
49 49
50 - /**  
51 - * 心跳发送频率,单位:毫秒  
52 - * <p>  
53 - * 默认:30 秒  
54 - */  
55 - private Long heartbeatInterval = 30000L;  
56 -}  
57 \ No newline at end of file 50 \ No newline at end of file
  51 +}
58 \ No newline at end of file 52 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/downstream/IotComponentDownstreamHandlerImpl.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.server.downstream;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
5 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -  
8 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS;  
9 -  
10 -/**  
11 - * 网络组件下行处理器实现  
12 - * <p>  
13 - * 处理来自主程序的设备控制指令  
14 - *  
15 - * @author haohao  
16 - */  
17 -@Slf4j  
18 -public class IotComponentDownstreamHandlerImpl implements IotDeviceDownstreamHandler {  
19 -  
20 - @Override  
21 - public CommonResult<Boolean> invokeDeviceService(IotDeviceServiceInvokeReqDTO invokeReqDTO) {  
22 - log.info("[invokeDeviceService][收到服务调用请求:{}]", invokeReqDTO);  
23 - // 在这里处理服务调用,可以根据设备类型转发到对应的处理器  
24 - // 如 MQTT 设备、HTTP 设备等的具体实现  
25 -  
26 - // 这里仅作为示例,实际应根据接入的组件进行转发  
27 - return CommonResult.success(true);  
28 - }  
29 -  
30 - @Override  
31 - public CommonResult<Boolean> getDeviceProperty(IotDevicePropertyGetReqDTO getReqDTO) {  
32 - log.info("[getDeviceProperty][收到属性获取请求:{}]", getReqDTO);  
33 - // 在这里处理属性获取请求  
34 -  
35 - // 这里仅作为示例,实际应根据接入的组件进行转发  
36 - return CommonResult.success(true);  
37 - }  
38 -  
39 - @Override  
40 - public CommonResult<Boolean> setDeviceProperty(IotDevicePropertySetReqDTO setReqDTO) {  
41 - log.info("[setDeviceProperty][收到属性设置请求:{}]", setReqDTO);  
42 - // 在这里处理属性设置请求  
43 -  
44 - // 这里仅作为示例,实际应根据接入的组件进行转发  
45 - return CommonResult.success(true);  
46 - }  
47 -  
48 - @Override  
49 - public CommonResult<Boolean> setDeviceConfig(IotDeviceConfigSetReqDTO setReqDTO) {  
50 - log.info("[setDeviceConfig][收到配置设置请求:{}]", setReqDTO);  
51 - // 在这里处理配置设置请求  
52 -  
53 - // 这里仅作为示例,实际应根据接入的组件进行转发  
54 - return CommonResult.success(true);  
55 - }  
56 -  
57 - @Override  
58 - public CommonResult<Boolean> upgradeDeviceOta(IotDeviceOtaUpgradeReqDTO upgradeReqDTO) {  
59 - log.info("[upgradeDeviceOta][收到OTA升级请求:{}]", upgradeReqDTO);  
60 - // 在这里处理OTA升级请求  
61 -  
62 - // 这里仅作为示例,实际应根据接入的组件进行转发  
63 - return CommonResult.success(true);  
64 - }  
65 -}  
66 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/downstream/IotComponentDownstreamServer.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.server.downstream;  
2 -  
3 -import cn.hutool.core.util.IdUtil;  
4 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
5 -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*;  
6 -import cn.iocoder.yudao.module.iot.net.component.core.downstream.IotDeviceDownstreamHandler;  
7 -import cn.iocoder.yudao.module.iot.net.component.server.config.IotNetComponentServerProperties;  
8 -import io.vertx.core.Vertx;  
9 -import io.vertx.core.http.HttpServer;  
10 -import io.vertx.core.json.Json;  
11 -import io.vertx.core.json.JsonObject;  
12 -import io.vertx.ext.web.Router;  
13 -import io.vertx.ext.web.RoutingContext;  
14 -import io.vertx.ext.web.handler.BodyHandler;  
15 -import lombok.extern.slf4j.Slf4j;  
16 -  
17 -import java.util.List;  
18 -import java.util.Map;  
19 -  
20 -/**  
21 - * 组件下行服务器,接收来自主程序的控制指令  
22 - *  
23 - * @author haohao  
24 - */  
25 -@Slf4j  
26 -public class IotComponentDownstreamServer {  
27 -  
28 - public static final String SERVICE_INVOKE_PATH = "/sys/:productKey/:deviceName/thing/service/:identifier";  
29 - public static final String PROPERTY_SET_PATH = "/sys/:productKey/:deviceName/thing/service/property/set";  
30 - public static final String PROPERTY_GET_PATH = "/sys/:productKey/:deviceName/thing/service/property/get";  
31 - public static final String CONFIG_SET_PATH = "/sys/:productKey/:deviceName/thing/service/config/set";  
32 - public static final String OTA_UPGRADE_PATH = "/sys/:productKey/:deviceName/thing/service/ota/upgrade";  
33 -  
34 - private final Vertx vertx;  
35 - private final HttpServer server;  
36 - private final IotNetComponentServerProperties properties;  
37 - private final IotDeviceDownstreamHandler downstreamHandler;  
38 -  
39 - public IotComponentDownstreamServer(IotNetComponentServerProperties properties,  
40 - IotDeviceDownstreamHandler downstreamHandler) {  
41 - this.properties = properties;  
42 - this.downstreamHandler = downstreamHandler;  
43 - // 创建 Vertx 实例  
44 - this.vertx = Vertx.vertx();  
45 - // 创建 Router 实例  
46 - Router router = Router.router(vertx);  
47 - router.route().handler(BodyHandler.create()); // 处理 Body  
48 -  
49 - // 服务调用路由  
50 - router.post(SERVICE_INVOKE_PATH).handler(this::handleServiceInvoke);  
51 - // 属性设置路由  
52 - router.post(PROPERTY_SET_PATH).handler(this::handlePropertySet);  
53 - // 属性获取路由  
54 - router.post(PROPERTY_GET_PATH).handler(this::handlePropertyGet);  
55 - // 配置设置路由  
56 - router.post(CONFIG_SET_PATH).handler(this::handleConfigSet);  
57 - // OTA 升级路由  
58 - router.post(OTA_UPGRADE_PATH).handler(this::handleOtaUpgrade);  
59 -  
60 - // 创建 HttpServer 实例  
61 - this.server = vertx.createHttpServer().requestHandler(router);  
62 - }  
63 -  
64 - /**  
65 - * 启动服务器  
66 - */  
67 - public void start() {  
68 - log.info("[start][开始启动下行服务器]");  
69 - server.listen(properties.getDownstreamPort())  
70 - .toCompletionStage()  
71 - .toCompletableFuture()  
72 - .join();  
73 - log.info("[start][下行服务器启动完成,端口({})]", server.actualPort());  
74 - }  
75 -  
76 - /**  
77 - * 停止服务器  
78 - */  
79 - public void stop() {  
80 - log.info("[stop][开始关闭下行服务器]");  
81 - try {  
82 - // 关闭 HTTP 服务器  
83 - if (server != null) {  
84 - server.close()  
85 - .toCompletionStage()  
86 - .toCompletableFuture()  
87 - .join();  
88 - }  
89 -  
90 - // 关闭 Vertx 实例  
91 - if (vertx != null) {  
92 - vertx.close()  
93 - .toCompletionStage()  
94 - .toCompletableFuture()  
95 - .join();  
96 - }  
97 - log.info("[stop][下行服务器关闭完成]");  
98 - } catch (Exception e) {  
99 - log.error("[stop][下行服务器关闭异常]", e);  
100 - throw new RuntimeException(e);  
101 - }  
102 - }  
103 -  
104 - /**  
105 - * 获取服务器端口  
106 - *  
107 - * @return 端口号  
108 - */  
109 - public int getPort() {  
110 - return server.actualPort();  
111 - }  
112 -  
113 - /**  
114 - * 处理服务调用请求  
115 - */  
116 - private void handleServiceInvoke(RoutingContext ctx) {  
117 - try {  
118 - // 解析路径参数  
119 - String productKey = ctx.pathParam("productKey");  
120 - String deviceName = ctx.pathParam("deviceName");  
121 - String identifier = ctx.pathParam("identifier");  
122 -  
123 - // 解析请求体  
124 - JsonObject body = ctx.body().asJsonObject();  
125 - String requestId = body.getString("requestId", IdUtil.fastSimpleUUID());  
126 - Object params = body.getMap().get("params");  
127 -  
128 - // 创建请求对象  
129 - IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO();  
130 - reqDTO.setRequestId(requestId);  
131 - reqDTO.setProductKey(productKey);  
132 - reqDTO.setDeviceName(deviceName);  
133 - reqDTO.setIdentifier(identifier);  
134 - reqDTO.setParams((Map<String, Object>) params);  
135 -  
136 - // 调用处理器  
137 - CommonResult<Boolean> result = downstreamHandler.invokeDeviceService(reqDTO);  
138 -  
139 - // 响应结果  
140 - ctx.response()  
141 - .putHeader("Content-Type", "application/json")  
142 - .end(Json.encode(result));  
143 - } catch (Exception e) {  
144 - log.error("[handleServiceInvoke][处理服务调用请求失败]", e);  
145 - ctx.response()  
146 - .setStatusCode(500)  
147 - .putHeader("Content-Type", "application/json")  
148 - .end(Json.encode(CommonResult.error(500, "处理服务调用请求失败:" + e.getMessage())));  
149 - }  
150 - }  
151 -  
152 - /**  
153 - * 处理属性设置请求  
154 - */  
155 - private void handlePropertySet(RoutingContext ctx) {  
156 - try {  
157 - // 解析路径参数  
158 - String productKey = ctx.pathParam("productKey");  
159 - String deviceName = ctx.pathParam("deviceName");  
160 -  
161 - // 解析请求体  
162 - JsonObject body = ctx.body().asJsonObject();  
163 - String requestId = body.getString("requestId", IdUtil.fastSimpleUUID());  
164 - Object properties = body.getMap().get("properties");  
165 -  
166 - // 创建请求对象  
167 - IotDevicePropertySetReqDTO reqDTO = new IotDevicePropertySetReqDTO();  
168 - reqDTO.setRequestId(requestId);  
169 - reqDTO.setProductKey(productKey);  
170 - reqDTO.setDeviceName(deviceName);  
171 - reqDTO.setProperties((Map<String, Object>) properties);  
172 -  
173 - // 调用处理器  
174 - CommonResult<Boolean> result = downstreamHandler.setDeviceProperty(reqDTO);  
175 -  
176 - // 响应结果  
177 - ctx.response()  
178 - .putHeader("Content-Type", "application/json")  
179 - .end(Json.encode(result));  
180 - } catch (Exception e) {  
181 - log.error("[handlePropertySet][处理属性设置请求失败]", e);  
182 - ctx.response()  
183 - .setStatusCode(500)  
184 - .putHeader("Content-Type", "application/json")  
185 - .end(Json.encode(CommonResult.error(500, "处理属性设置请求失败:" + e.getMessage())));  
186 - }  
187 - }  
188 -  
189 - /**  
190 - * 处理属性获取请求  
191 - */  
192 - private void handlePropertyGet(RoutingContext ctx) {  
193 - try {  
194 - // 解析路径参数  
195 - String productKey = ctx.pathParam("productKey");  
196 - String deviceName = ctx.pathParam("deviceName");  
197 -  
198 - // 解析请求体  
199 - JsonObject body = ctx.body().asJsonObject();  
200 - String requestId = body.getString("requestId", IdUtil.fastSimpleUUID());  
201 - Object identifiers = body.getMap().get("identifiers");  
202 -  
203 - // 创建请求对象  
204 - IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO();  
205 - reqDTO.setRequestId(requestId);  
206 - reqDTO.setProductKey(productKey);  
207 - reqDTO.setDeviceName(deviceName);  
208 - reqDTO.setIdentifiers((List<String>) identifiers);  
209 -  
210 - // 调用处理器  
211 - CommonResult<Boolean> result = downstreamHandler.getDeviceProperty(reqDTO);  
212 -  
213 - // 响应结果  
214 - ctx.response()  
215 - .putHeader("Content-Type", "application/json")  
216 - .end(Json.encode(result));  
217 - } catch (Exception e) {  
218 - log.error("[handlePropertyGet][处理属性获取请求失败]", e);  
219 - ctx.response()  
220 - .setStatusCode(500)  
221 - .putHeader("Content-Type", "application/json")  
222 - .end(Json.encode(CommonResult.error(500, "处理属性获取请求失败:" + e.getMessage())));  
223 - }  
224 - }  
225 -  
226 - /**  
227 - * 处理配置设置请求  
228 - */  
229 - private void handleConfigSet(RoutingContext ctx) {  
230 - try {  
231 - // 解析路径参数  
232 - String productKey = ctx.pathParam("productKey");  
233 - String deviceName = ctx.pathParam("deviceName");  
234 -  
235 - // 解析请求体  
236 - JsonObject body = ctx.body().asJsonObject();  
237 - String requestId = body.getString("requestId", IdUtil.fastSimpleUUID());  
238 - Object config = body.getMap().get("config");  
239 -  
240 - // 创建请求对象  
241 - IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO();  
242 - reqDTO.setRequestId(requestId);  
243 - reqDTO.setProductKey(productKey);  
244 - reqDTO.setDeviceName(deviceName);  
245 - reqDTO.setConfig((Map<String, Object>) config);  
246 -  
247 - // 调用处理器  
248 - CommonResult<Boolean> result = downstreamHandler.setDeviceConfig(reqDTO);  
249 -  
250 - // 响应结果  
251 - ctx.response()  
252 - .putHeader("Content-Type", "application/json")  
253 - .end(Json.encode(result));  
254 - } catch (Exception e) {  
255 - log.error("[handleConfigSet][处理配置设置请求失败]", e);  
256 - ctx.response()  
257 - .setStatusCode(500)  
258 - .putHeader("Content-Type", "application/json")  
259 - .end(Json.encode(CommonResult.error(500, "处理配置设置请求失败:" + e.getMessage())));  
260 - }  
261 - }  
262 -  
263 - /**  
264 - * 处理 OTA 升级请求  
265 - */  
266 - private void handleOtaUpgrade(RoutingContext ctx) {  
267 - try {  
268 - // 解析路径参数  
269 - String productKey = ctx.pathParam("productKey");  
270 - String deviceName = ctx.pathParam("deviceName");  
271 -  
272 - // 解析请求体  
273 - JsonObject body = ctx.body().asJsonObject();  
274 - String requestId = body.getString("requestId", IdUtil.fastSimpleUUID());  
275 - Object data = body.getMap().get("data");  
276 -  
277 - // 创建请求对象  
278 - IotDeviceOtaUpgradeReqDTO reqDTO = new IotDeviceOtaUpgradeReqDTO();  
279 - reqDTO.setRequestId(requestId);  
280 - reqDTO.setProductKey(productKey);  
281 - reqDTO.setDeviceName(deviceName);  
282 -  
283 - // 数据采用 IotDeviceOtaUpgradeReqDTO.build 方法转换  
284 - if (data instanceof Map) {  
285 - IotDeviceOtaUpgradeReqDTO builtDTO = IotDeviceOtaUpgradeReqDTO.build((Map<?, ?>) data);  
286 - reqDTO.setFirmwareId(builtDTO.getFirmwareId());  
287 - reqDTO.setVersion(builtDTO.getVersion());  
288 - reqDTO.setSignMethod(builtDTO.getSignMethod());  
289 - reqDTO.setFileSign(builtDTO.getFileSign());  
290 - reqDTO.setFileSize(builtDTO.getFileSize());  
291 - reqDTO.setFileUrl(builtDTO.getFileUrl());  
292 - reqDTO.setInformation(builtDTO.getInformation());  
293 - }  
294 -  
295 - // 调用处理器  
296 - CommonResult<Boolean> result = downstreamHandler.upgradeDeviceOta(reqDTO);  
297 -  
298 - // 响应结果  
299 - ctx.response()  
300 - .putHeader("Content-Type", "application/json")  
301 - .end(Json.encode(result));  
302 - } catch (Exception e) {  
303 - log.error("[handleOtaUpgrade][处理OTA升级请求失败]", e);  
304 - ctx.response()  
305 - .setStatusCode(500)  
306 - .putHeader("Content-Type", "application/json")  
307 - .end(Json.encode(CommonResult.error(500, "处理OTA升级请求失败:" + e.getMessage())));  
308 - }  
309 - }  
310 -}  
311 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/heartbeat/IotComponentHeartbeatJob.java deleted
1 -package cn.iocoder.yudao.module.iot.net.component.server.heartbeat;  
2 -  
3 -import cn.hutool.system.SystemUtil;  
4 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
5 -import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;  
6 -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotPluginInstanceHeartbeatReqDTO;  
7 -import cn.iocoder.yudao.module.iot.net.component.server.config.IotNetComponentServerProperties;  
8 -import cn.iocoder.yudao.module.iot.net.component.server.downstream.IotComponentDownstreamServer;  
9 -import lombok.extern.slf4j.Slf4j;  
10 -  
11 -import java.util.concurrent.ScheduledExecutorService;  
12 -import java.util.concurrent.ScheduledThreadPoolExecutor;  
13 -import java.util.concurrent.TimeUnit;  
14 -  
15 -// TODO @haohao:有办法服用 yudao-module-iot-net-component-core 的么?就是 server,只是一个启动器,没什么特殊的功能;  
16 -/**  
17 - * IoT 组件心跳任务  
18 - * <p>  
19 - * 定期向主程序发送心跳,报告组件服务状态  
20 - *  
21 - * @author haohao  
22 - */  
23 -@Slf4j  
24 -public class IotComponentHeartbeatJob {  
25 -  
26 - private final IotDeviceUpstreamApi deviceUpstreamApi;  
27 - private final IotComponentDownstreamServer downstreamServer;  
28 - private final IotNetComponentServerProperties properties;  
29 - private ScheduledExecutorService executorService;  
30 -  
31 - public IotComponentHeartbeatJob(IotDeviceUpstreamApi deviceUpstreamApi,  
32 - IotComponentDownstreamServer downstreamServer,  
33 - IotNetComponentServerProperties properties) {  
34 - this.deviceUpstreamApi = deviceUpstreamApi;  
35 - this.downstreamServer = downstreamServer;  
36 - this.properties = properties;  
37 - }  
38 -  
39 - /**  
40 - * 初始化心跳任务  
41 - */  
42 - public void init() {  
43 - log.info("[init][开始初始化心跳任务]");  
44 - // 创建一个单线程的调度线程池  
45 - executorService = new ScheduledThreadPoolExecutor(1);  
46 - // 延迟 5 秒后开始执行,避免服务刚启动就发送心跳  
47 - executorService.scheduleAtFixedRate(this::sendHeartbeat,  
48 - 5000, properties.getHeartbeatInterval(), TimeUnit.MILLISECONDS);  
49 - log.info("[init][心跳任务初始化完成]");  
50 - }  
51 -  
52 - /**  
53 - * 停止心跳任务  
54 - */  
55 - public void stop() {  
56 - log.info("[stop][开始停止心跳任务]");  
57 - if (executorService != null) {  
58 - executorService.shutdown();  
59 - executorService = null;  
60 - }  
61 - log.info("[stop][心跳任务已停止]");  
62 - }  
63 -  
64 - /**  
65 - * 发送心跳  
66 - */  
67 - private void sendHeartbeat() {  
68 - try {  
69 - // 创建心跳请求  
70 - IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO = new IotPluginInstanceHeartbeatReqDTO();  
71 - // 设置插件标识  
72 - heartbeatReqDTO.setPluginKey(properties.getServerKey());  
73 - // 设置进程ID  
74 - heartbeatReqDTO.setProcessId(String.valueOf(ProcessHandle.current().pid()));  
75 - // 设置IP和端口  
76 - try {  
77 - String hostIp = SystemUtil.getHostInfo().getAddress();  
78 - heartbeatReqDTO.setHostIp(hostIp);  
79 - heartbeatReqDTO.setDownstreamPort(downstreamServer.getPort());  
80 - } catch (Exception e) {  
81 - log.warn("[sendHeartbeat][获取本地主机信息异常]", e);  
82 - }  
83 - // 设置在线状态  
84 - heartbeatReqDTO.setOnline(true);  
85 -  
86 - // 发送心跳  
87 - CommonResult<Boolean> result = deviceUpstreamApi.heartbeatPluginInstance(heartbeatReqDTO);  
88 - if (result != null && result.isSuccess()) {  
89 - log.debug("[sendHeartbeat][发送心跳成功:{}]", heartbeatReqDTO);  
90 - } else {  
91 - log.error("[sendHeartbeat][发送心跳失败:{}, 结果:{}]", heartbeatReqDTO, result);  
92 - }  
93 - } catch (Exception e) {  
94 - log.error("[sendHeartbeat][发送心跳异常]", e);  
95 - }  
96 - }  
97 -  
98 -}  
99 \ No newline at end of file 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-server/src/main/java/cn/iocoder/yudao/module/iot/net/component/server/upstream/IotComponentUpstreamClient.java
@@ -69,12 +69,6 @@ public class IotComponentUpstreamClient implements IotDeviceUpstreamApi { @@ -69,12 +69,6 @@ public class IotComponentUpstreamClient implements IotDeviceUpstreamApi {
69 return doPost(url, reportReqDTO); 69 return doPost(url, reportReqDTO);
70 } 70 }
71 71
72 - @Override  
73 - public CommonResult<Boolean> heartbeatPluginInstance(IotPluginInstanceHeartbeatReqDTO heartbeatReqDTO) {  
74 - String url = properties.getUpstreamUrl() + URL_PREFIX + "/heartbeat-plugin-instance";  
75 - return doPost(url, heartbeatReqDTO);  
76 - }  
77 -  
78 @SuppressWarnings("unchecked") 72 @SuppressWarnings("unchecked")
79 private <T> CommonResult<Boolean> doPost(String url, T requestBody) { 73 private <T> CommonResult<Boolean> doPost(String url, T requestBody) {
80 try { 74 try {
@@ -87,4 +81,4 @@ public class IotComponentUpstreamClient implements IotDeviceUpstreamApi { @@ -87,4 +81,4 @@ public class IotComponentUpstreamClient implements IotDeviceUpstreamApi {
87 return CommonResult.error(INTERNAL_SERVER_ERROR); 81 return CommonResult.error(INTERNAL_SERVER_ERROR);
88 } 82 }
89 } 83 }
90 -}  
91 \ No newline at end of file 84 \ No newline at end of file
  85 +}
92 \ No newline at end of file 86 \ 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
@@ -17,8 +17,6 @@ yudao: @@ -17,8 +17,6 @@ yudao:
17 base-package: cn.iocoder.yudao # 主项目包路径,确保正确 17 base-package: cn.iocoder.yudao # 主项目包路径,确保正确
18 iot: 18 iot:
19 component: 19 component:
20 - # 这里可以覆盖或添加 component-core 中的通用配置  
21 - instance-heartbeat-timeout: 30000 # 心跳超时时间  
22 20
23 # 网络组件服务器专用配置 21 # 网络组件服务器专用配置
24 server: 22 server:
@@ -33,9 +31,6 @@ yudao: @@ -33,9 +31,6 @@ yudao:
33 # 组件服务唯一标识 31 # 组件服务唯一标识
34 server-key: yudao-module-iot-net-component-server 32 server-key: yudao-module-iot-net-component-server
35 33
36 - # 心跳频率,单位:毫秒  
37 - heartbeat-interval: 30000  
38 -  
39 # ==================================== 34 # ====================================
40 # 针对引入的 HTTP 组件的配置 35 # 针对引入的 HTTP 组件的配置
41 # ==================================== 36 # ====================================