Commit 02c3aa748b8ed45be1c438cdc91563422b388606
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
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 | # ==================================== |