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 80 @PostMapping(PREFIX + "/authenticate-emqx-connection")
81 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 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 21  
22 22 @Resource
23 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 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 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 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 3 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
5 4 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
6 5 import org.springframework.web.multipart.MultipartFile;
... ... @@ -15,13 +14,6 @@ import java.time.LocalDateTime;
15 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 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 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 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 5 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO;
8 6 import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
9 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 9 import jakarta.annotation.Resource;
12 10 import lombok.extern.slf4j.Slf4j;
13 11 import org.springframework.beans.factory.annotation.Value;
14   -import org.springframework.context.annotation.Lazy;
15 12 import org.springframework.stereotype.Service;
16 13 import org.springframework.validation.annotation.Validated;
17 14 import org.springframework.web.multipart.MultipartFile;
... ... @@ -32,10 +29,6 @@ import java.util.concurrent.TimeUnit;
32 29 public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
33 30  
34 31 @Resource
35   - @Lazy // 延迟加载,避免循环依赖
36   - private IotPluginConfigService pluginConfigService;
37   -
38   - @Resource
39 32 private IotPluginInstanceMapper pluginInstanceMapper;
40 33  
41 34 @Resource
... ... @@ -48,47 +41,6 @@ public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
48 41 private String pluginsDir;
49 42  
50 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 44 public int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime) {
93 45 List<IotPluginInstanceDO> list = pluginInstanceMapper.selectListByHeartbeatTimeLt(maxHeartbeatTime);
94 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 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 3 import cn.iocoder.yudao.module.iot.net.component.core.upstream.IotDeviceUpstreamClient;
9   -import org.springframework.beans.factory.annotation.Qualifier;
10 4 import org.springframework.boot.autoconfigure.AutoConfiguration;
11   -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
12 5 import org.springframework.boot.context.properties.EnableConfigurationProperties;
13 6 import org.springframework.context.annotation.Bean;
14 7 import org.springframework.scheduling.annotation.EnableScheduling;
15 8  
16   -// TODO @haohao:应该不用写 spring.factories 拉,因为被 imports 替代啦
17 9 /**
18 10 * IoT 网络组件的通用自动配置类
19 11 *
... ... @@ -25,37 +17,11 @@ import org.springframework.scheduling.annotation.EnableScheduling;
25 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 22 @Bean
58 23 public IotDeviceUpstreamClient deviceUpstreamClient() {
59 24 return new IotDeviceUpstreamClient();
60 25 }
  26 +
61 27 }
62 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 21 */
22 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 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 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 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 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 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 2  
3 3 import cn.hutool.core.util.IdUtil;
4 4 import cn.hutool.core.util.ObjUtil;
5   -import cn.hutool.system.SystemUtil;
6 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 6 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.IotDeviceUpstreamServer;
13 7 import io.vertx.core.Vertx;
14 8 import io.vertx.mqtt.MqttClient;
... ... @@ -38,16 +32,6 @@ import org.springframework.context.event.EventListener;
38 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 35 * 初始化 EMQX 组件
52 36 *
53 37 * @param event 应用启动事件
... ... @@ -57,21 +41,7 @@ public class IotNetComponentEmqxAutoConfiguration {
57 41 log.info("[IotNetComponentEmqxAutoConfiguration][开始初始化]");
58 42  
59 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 46 log.info("[initialize][IoT EMQX 组件初始化完成]");
77 47 }
... ... @@ -89,15 +59,6 @@ public class IotNetComponentEmqxAutoConfiguration {
89 59 */
90 60 @Bean
91 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 62 MqttClientOptions options = new MqttClientOptions()
102 63 .setClientId("yudao-iot-downstream-" + IdUtil.fastSimpleUUID())
103 64 .setUsername(emqxProperties.getMqttUsername())
... ... @@ -115,16 +76,8 @@ public class IotNetComponentEmqxAutoConfiguration {
115 76 IotDeviceUpstreamApi deviceUpstreamApi,
116 77 IotNetComponentEmqxProperties emqxProperties,
117 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 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 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 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 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 3 import cn.hutool.core.util.ArrayUtil;
4 4 import cn.hutool.core.util.StrUtil;
5 5 import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
6   -import cn.iocoder.yudao.module.iot.net.component.core.heartbeat.IotNetComponentRegistry;
7 6 import cn.iocoder.yudao.module.iot.net.component.emqx.config.IotNetComponentEmqxProperties;
8 7 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceAuthVertxHandler;
9 8 import cn.iocoder.yudao.module.iot.net.component.emqx.upstream.router.IotDeviceMqttMessageHandler;
... ... @@ -40,7 +39,6 @@ public class IotDeviceUpstreamServer {
40 39 private final MqttClient client;
41 40 private final IotNetComponentEmqxProperties emqxProperties;
42 41 private final IotDeviceMqttMessageHandler mqttMessageHandler;
43   - private final IotNetComponentRegistry componentRegistry;
44 42  
45 43 /**
46 44 * 服务运行状态标志
... ... @@ -50,12 +48,10 @@ public class IotDeviceUpstreamServer {
50 48 public IotDeviceUpstreamServer(IotNetComponentEmqxProperties emqxProperties,
51 49 IotDeviceUpstreamApi deviceUpstreamApi,
52 50 Vertx vertx,
53   - MqttClient client,
54   - IotNetComponentRegistry componentRegistry) {
  51 + MqttClient client) {
55 52 this.vertx = vertx;
56 53 this.emqxProperties = emqxProperties;
57 54 this.client = client;
58   - this.componentRegistry = componentRegistry;
59 55  
60 56 // 创建 Router 实例
61 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 5 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBusSubscriber;
6 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 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 8 import cn.iocoder.yudao.module.iot.net.component.http.upstream.IotDeviceUpstreamServer;
11 9 import io.vertx.core.Vertx;
12 10 import lombok.extern.slf4j.Slf4j;
... ... @@ -89,14 +87,4 @@ public class IotNetComponentHttpAutoConfiguration {
89 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 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 1 package cn.iocoder.yudao.module.iot.net.component.server.config;
2 2  
3 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 4 import cn.iocoder.yudao.module.iot.net.component.server.upstream.IotComponentUpstreamClient;
9 5 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10 6 import org.springframework.boot.context.properties.EnableConfigurationProperties;
... ... @@ -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 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 47 */
48 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 50 \ No newline at end of file
  51 +}
58 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 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 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 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 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 72 @SuppressWarnings("unchecked")
79 73 private <T> CommonResult<Boolean> doPost(String url, T requestBody) {
80 74 try {
... ... @@ -87,4 +81,4 @@ public class IotComponentUpstreamClient implements IotDeviceUpstreamApi {
87 81 return CommonResult.error(INTERNAL_SERVER_ERROR);
88 82 }
89 83 }
90   -}
91 84 \ No newline at end of file
  85 +}
92 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 17 base-package: cn.iocoder.yudao # 主项目包路径,确保正确
18 18 iot:
19 19 component:
20   - # 这里可以覆盖或添加 component-core 中的通用配置
21   - instance-heartbeat-timeout: 30000 # 心跳超时时间
22 20  
23 21 # 网络组件服务器专用配置
24 22 server:
... ... @@ -33,9 +31,6 @@ yudao:
33 31 # 组件服务唯一标识
34 32 server-key: yudao-module-iot-net-component-server
35 33  
36   - # 心跳频率,单位:毫秒
37   - heartbeat-interval: 30000
38   -
39 34 # ====================================
40 35 # 针对引入的 HTTP 组件的配置
41 36 # ====================================
... ...