Commit 4319220750a142bf62c5ae42baa99472708be047

Authored by YunaiV
1 parent e275cb57

feat(iot):【协议改造】modbus-tcp:改造新的协议方式

Showing 11 changed files with 300 additions and 323 deletions
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java
1 package cn.iocoder.yudao.module.iot.gateway.config; 1 package cn.iocoder.yudao.module.iot.gateway.config;
2 2
3 -import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;  
4 import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocolManager; 3 import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocolManager;
5 -import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxAuthEventProtocol;  
6 -import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxDownstreamSubscriber;  
7 -import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxUpstreamProtocol;  
8 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.*;  
9 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient;  
10 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;  
11 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService;  
12 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager;  
13 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpPollScheduler;  
14 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpDownstreamHandler;  
15 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpUpstreamHandler;  
16 -import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttDownstreamSubscriber;  
17 -import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttUpstreamProtocol;  
18 -import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.manager.IotMqttConnectionManager;  
19 -import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.router.IotMqttDownstreamHandler;  
20 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.IotModbusTcpDownstreamSubscriber;  
21 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.IotModbusTcpUpstreamProtocol;  
22 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient;  
23 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;  
24 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService;  
25 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager;  
26 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpPollScheduler;  
27 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpDownstreamHandler;  
28 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpUpstreamHandler;  
29 import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializerManager; 4 import cn.iocoder.yudao.module.iot.gateway.serialize.IotMessageSerializerManager;
30 -import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;  
31 -import io.vertx.core.Vertx;  
32 -import lombok.extern.slf4j.Slf4j;  
33 -import org.redisson.api.RedissonClient;  
34 -import org.springframework.beans.factory.annotation.Qualifier;  
35 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
36 -import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;  
37 -import io.vertx.core.Vertx;  
38 -import lombok.extern.slf4j.Slf4j;  
39 -import org.redisson.api.RedissonClient;  
40 -import org.springframework.beans.factory.annotation.Qualifier;  
41 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
42 import org.springframework.boot.context.properties.EnableConfigurationProperties; 5 import org.springframework.boot.context.properties.EnableConfigurationProperties;
43 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Bean;
44 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Configuration;
45 8
  9 +/**
  10 + * IoT 网关配置类
  11 + *
  12 + * @author 芋道源码
  13 + */
46 @Configuration 14 @Configuration
47 @EnableConfigurationProperties(IotGatewayProperties.class) 15 @EnableConfigurationProperties(IotGatewayProperties.class)
48 public class IotGatewayConfiguration { 16 public class IotGatewayConfiguration {
@@ -57,86 +25,4 @@ public class IotGatewayConfiguration { @@ -57,86 +25,4 @@ public class IotGatewayConfiguration {
57 return new IotProtocolManager(gatewayProperties); 25 return new IotProtocolManager(gatewayProperties);
58 } 26 }
59 27
60 - /**  
61 - * IoT 网关 Modbus TCP 协议配置类  
62 - */  
63 - @Configuration  
64 - @ConditionalOnProperty(prefix = "yudao.iot.gateway.protocol.modbus-tcp", name = "enabled", havingValue = "true")  
65 - @Slf4j  
66 - public static class ModbusTcpProtocolConfiguration {  
67 -  
68 - @Bean(name = "modbusTcpVertx", destroyMethod = "close")  
69 - public Vertx modbusTcpVertx() {  
70 - return Vertx.vertx();  
71 - }  
72 -  
73 - @Bean  
74 - public IotModbusDataConverter iotModbusDataConverter() {  
75 - return new IotModbusDataConverter();  
76 - }  
77 -  
78 - @Bean  
79 - public IotModbusTcpClient iotModbusTcpClient() {  
80 - return new IotModbusTcpClient();  
81 - }  
82 -  
83 - @Bean  
84 - public IotModbusTcpConnectionManager iotModbusTcpConnectionManager(  
85 - RedissonClient redissonClient,  
86 - @Qualifier("modbusTcpVertx") Vertx modbusTcpVertx) {  
87 - return new IotModbusTcpConnectionManager(redissonClient, modbusTcpVertx);  
88 - }  
89 -  
90 - @Bean  
91 - public IotModbusTcpConfigCacheService iotModbusTcpConfigCacheService(  
92 - cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi deviceApi) {  
93 - return new IotModbusTcpConfigCacheService(deviceApi);  
94 - }  
95 -  
96 - @Bean  
97 - public IotModbusTcpUpstreamHandler iotModbusTcpUpstreamHandler(  
98 - IotDeviceMessageService messageService,  
99 - IotModbusDataConverter dataConverter) {  
100 - return new IotModbusTcpUpstreamHandler(messageService, dataConverter);  
101 - }  
102 -  
103 - @Bean  
104 - public IotModbusTcpPollScheduler iotModbusTcpPollScheduler(  
105 - @Qualifier("modbusTcpVertx") Vertx modbusTcpVertx,  
106 - IotModbusTcpConnectionManager connectionManager,  
107 - IotModbusTcpClient modbusClient,  
108 - IotModbusTcpUpstreamHandler upstreamHandler) {  
109 - return new IotModbusTcpPollScheduler(modbusTcpVertx, connectionManager, modbusClient, upstreamHandler);  
110 - }  
111 -  
112 - @Bean  
113 - public IotModbusTcpDownstreamHandler iotModbusTcpDownstreamHandler(  
114 - IotModbusTcpConnectionManager connectionManager,  
115 - IotModbusTcpClient modbusClient,  
116 - IotModbusDataConverter dataConverter,  
117 - IotModbusTcpConfigCacheService configCacheService) {  
118 - return new IotModbusTcpDownstreamHandler(connectionManager, modbusClient, dataConverter, configCacheService);  
119 - }  
120 -  
121 - @Bean  
122 - public IotModbusTcpUpstreamProtocol iotModbusTcpUpstreamProtocol(IotGatewayProperties gatewayProperties,  
123 - IotDeviceMessageService messageService,  
124 - IotModbusTcpConnectionManager connectionManager,  
125 - IotModbusTcpPollScheduler pollScheduler,  
126 - IotModbusTcpConfigCacheService configCacheService,  
127 - IotModbusTcpUpstreamHandler upstreamHandler,  
128 - @Qualifier("modbusTcpVertx") Vertx modbusTcpVertx) {  
129 - return new IotModbusTcpUpstreamProtocol(gatewayProperties.getProtocol().getModbusTcp(),  
130 - messageService, connectionManager, pollScheduler, configCacheService, upstreamHandler, modbusTcpVertx);  
131 - }  
132 -  
133 - @Bean  
134 - public IotModbusTcpDownstreamSubscriber iotModbusTcpDownstreamSubscriber(IotModbusTcpUpstreamProtocol upstreamProtocol,  
135 - IotModbusTcpDownstreamHandler downstreamHandler,  
136 - IotMessageBus messageBus) {  
137 - return new IotModbusTcpDownstreamSubscriber(upstreamProtocol, downstreamHandler, messageBus);  
138 - }  
139 -  
140 - }  
141 -  
142 } 28 }
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayProperties.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
4 import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapConfig; 4 import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapConfig;
5 import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxConfig; 5 import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxConfig;
6 import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpConfig; 6 import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpConfig;
  7 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.IotModbusTcpConfig;
7 import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttConfig; 8 import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttConfig;
8 import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.IotTcpConfig; 9 import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.IotTcpConfig;
9 import cn.iocoder.yudao.module.iot.gateway.protocol.udp.IotUdpConfig; 10 import cn.iocoder.yudao.module.iot.gateway.protocol.udp.IotUdpConfig;
@@ -166,6 +167,12 @@ public class IotGatewayProperties { @@ -166,6 +167,12 @@ public class IotGatewayProperties {
166 @Valid 167 @Valid
167 private IotEmqxConfig emqx; 168 private IotEmqxConfig emqx;
168 169
  170 + /**
  171 + * Modbus TCP 协议配置
  172 + */
  173 + @Valid
  174 + private IotModbusTcpConfig modbusTcp;
  175 +
169 } 176 }
170 177
171 /** 178 /**
@@ -216,31 +223,4 @@ public class IotGatewayProperties { @@ -216,31 +223,4 @@ public class IotGatewayProperties {
216 223
217 } 224 }
218 225
219 - @Data  
220 - public static class ProtocolProperties {  
221 -  
222 - /**  
223 - * Modbus TCP 组件配置  
224 - */  
225 - private ModbusTcpProperties modbusTcp;  
226 -  
227 - }  
228 -  
229 - @Data  
230 - public static class ModbusTcpProperties {  
231 -  
232 - /**  
233 - * 是否开启  
234 - */  
235 - @NotNull(message = "是否开启不能为空")  
236 - private Boolean enabled;  
237 -  
238 - /**  
239 - * 配置刷新间隔(秒)  
240 - */  
241 - @NotNull(message = "配置刷新间隔不能为空")  
242 - private Integer configRefreshInterval = 30;  
243 -  
244 - }  
245 -  
246 } 226 }
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/IotProtocolManager.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties; @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;
7 import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapProtocol; 7 import cn.iocoder.yudao.module.iot.gateway.protocol.coap.IotCoapProtocol;
8 import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxProtocol; 8 import cn.iocoder.yudao.module.iot.gateway.protocol.emqx.IotEmqxProtocol;
9 import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpProtocol; 9 import cn.iocoder.yudao.module.iot.gateway.protocol.http.IotHttpProtocol;
  10 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.IotModbusTcpProtocol;
10 import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttProtocol; 11 import cn.iocoder.yudao.module.iot.gateway.protocol.mqtt.IotMqttProtocol;
11 import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.IotTcpProtocol; 12 import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.IotTcpProtocol;
12 import cn.iocoder.yudao.module.iot.gateway.protocol.udp.IotUdpProtocol; 13 import cn.iocoder.yudao.module.iot.gateway.protocol.udp.IotUdpProtocol;
@@ -112,6 +113,8 @@ public class IotProtocolManager implements SmartLifecycle { @@ -112,6 +113,8 @@ public class IotProtocolManager implements SmartLifecycle {
112 return createMqttProtocol(config); 113 return createMqttProtocol(config);
113 case EMQX: 114 case EMQX:
114 return createEmqxProtocol(config); 115 return createEmqxProtocol(config);
  116 + case MODBUS_TCP:
  117 + return createModbusTcpProtocol(config);
115 default: 118 default:
116 throw new IllegalArgumentException(String.format( 119 throw new IllegalArgumentException(String.format(
117 "[createProtocol][协议实例 %s 的协议类型 %s 暂不支持]", config.getId(), protocolType)); 120 "[createProtocol][协议实例 %s 的协议类型 %s 暂不支持]", config.getId(), protocolType));
@@ -188,4 +191,14 @@ public class IotProtocolManager implements SmartLifecycle { @@ -188,4 +191,14 @@ public class IotProtocolManager implements SmartLifecycle {
188 return new IotEmqxProtocol(config); 191 return new IotEmqxProtocol(config);
189 } 192 }
190 193
  194 + /**
  195 + * 创建 Modbus TCP 协议实例
  196 + *
  197 + * @param config 协议实例配置
  198 + * @return Modbus TCP 协议实例
  199 + */
  200 + private IotModbusTcpProtocol createModbusTcpProtocol(IotGatewayProperties.ProtocolProperties config) {
  201 + return new IotModbusTcpProtocol(config);
  202 + }
  203 +
191 } 204 }
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/IotModbusTcpConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp;
  2 +
  3 +import jakarta.validation.constraints.Min;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +/**
  8 + * IoT Modbus TCP 协议配置
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@Data
  13 +public class IotModbusTcpConfig {
  14 +
  15 + /**
  16 + * 配置刷新间隔(秒)
  17 + */
  18 + @NotNull(message = "配置刷新间隔不能为空")
  19 + @Min(value = 1, message = "配置刷新间隔不能小于 1 秒")
  20 + private Integer configRefreshInterval = 30;
  21 +
  22 +}
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/IotModbusTcpProtocol.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.extra.spring.SpringUtil;
  5 +import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
  6 +import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO;
  7 +import cn.iocoder.yudao.module.iot.core.enums.IotProtocolTypeEnum;
  8 +import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
  9 +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
  10 +import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties.ProtocolProperties;
  11 +import cn.iocoder.yudao.module.iot.gateway.protocol.IotProtocol;
  12 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient;
  13 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;
  14 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.downstream.IotModbusTcpDownstreamHandler;
  15 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.downstream.IotModbusTcpDownstreamSubscriber;
  16 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.upstream.IotModbusTcpUpstreamHandler;
  17 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService;
  18 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager;
  19 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpPollScheduler;
  20 +import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
  21 +import io.vertx.core.Vertx;
  22 +import lombok.Getter;
  23 +import lombok.extern.slf4j.Slf4j;
  24 +import org.redisson.api.RedissonClient;
  25 +
  26 +import java.util.List;
  27 +import java.util.concurrent.TimeUnit;
  28 +
  29 +/**
  30 + * IoT 网关 Modbus TCP 协议:主动轮询 Modbus 从站设备数据
  31 + *
  32 + * @author 芋道源码
  33 + */
  34 +@Slf4j
  35 +public class IotModbusTcpProtocol implements IotProtocol {
  36 +
  37 + /**
  38 + * 协议配置
  39 + */
  40 + private final ProtocolProperties properties;
  41 + /**
  42 + * 服务器 ID(用于消息追踪,全局唯一)
  43 + */
  44 + @Getter
  45 + private final String serverId;
  46 +
  47 + /**
  48 + * 运行状态
  49 + */
  50 + @Getter
  51 + private volatile boolean running = false;
  52 +
  53 + /**
  54 + * Vert.x 实例
  55 + */
  56 + private final Vertx vertx;
  57 + /**
  58 + * 配置刷新定时器 ID
  59 + */
  60 + private Long configRefreshTimerId;
  61 +
  62 + /**
  63 + * 连接管理器
  64 + */
  65 + private final IotModbusTcpConnectionManager connectionManager;
  66 + /**
  67 + * 下行消息订阅者
  68 + */
  69 + private final IotModbusTcpDownstreamSubscriber downstreamSubscriber;
  70 +
  71 + private final IotModbusTcpConfigCacheService configCacheService;
  72 + private final IotModbusTcpPollScheduler pollScheduler;
  73 +
  74 + public IotModbusTcpProtocol(ProtocolProperties properties) {
  75 + IotModbusTcpConfig modbusTcpConfig = properties.getModbusTcp();
  76 + Assert.notNull(modbusTcpConfig, "Modbus TCP 协议配置(modbusTcp)不能为空");
  77 + this.properties = properties;
  78 + this.serverId = IotDeviceMessageUtils.generateServerId(properties.getPort());
  79 +
  80 + // 初始化 Vertx
  81 + this.vertx = Vertx.vertx();
  82 +
  83 + // 初始化 Manager
  84 + RedissonClient redissonClient = SpringUtil.getBean(RedissonClient.class);
  85 + IotDeviceCommonApi deviceApi = SpringUtil.getBean(IotDeviceCommonApi.class);
  86 + this.connectionManager = new IotModbusTcpConnectionManager(redissonClient, vertx);
  87 + this.configCacheService = new IotModbusTcpConfigCacheService(deviceApi);
  88 +
  89 + // 初始化 Handler
  90 + IotModbusDataConverter dataConverter = new IotModbusDataConverter();
  91 + IotModbusTcpClient modbusClient = new IotModbusTcpClient();
  92 + IotDeviceMessageService messageService = SpringUtil.getBean(IotDeviceMessageService.class);
  93 + IotModbusTcpUpstreamHandler upstreamHandler = new IotModbusTcpUpstreamHandler(messageService, dataConverter, serverId);
  94 + IotModbusTcpDownstreamHandler downstreamHandler = new IotModbusTcpDownstreamHandler(connectionManager,
  95 + modbusClient, dataConverter, configCacheService);
  96 +
  97 + // 初始化轮询调度器
  98 + this.pollScheduler = new IotModbusTcpPollScheduler(vertx, connectionManager, modbusClient, upstreamHandler);
  99 +
  100 + // 初始化下行消息订阅者
  101 + IotMessageBus messageBus = SpringUtil.getBean(IotMessageBus.class);
  102 + this.downstreamSubscriber = new IotModbusTcpDownstreamSubscriber(this, downstreamHandler, messageBus);
  103 + }
  104 +
  105 + @Override
  106 + public String getId() {
  107 + return properties.getId();
  108 + }
  109 +
  110 + @Override
  111 + public IotProtocolTypeEnum getType() {
  112 + return IotProtocolTypeEnum.MODBUS_TCP;
  113 + }
  114 +
  115 + @Override
  116 + public void start() {
  117 + if (running) {
  118 + log.warn("[start][IoT Modbus TCP 协议 {} 已经在运行中]", getId());
  119 + return;
  120 + }
  121 +
  122 + try {
  123 + // 1.1 首次加载配置
  124 + refreshConfig();
  125 + // 1.2 启动配置刷新定时器
  126 + int refreshInterval = properties.getModbusTcp().getConfigRefreshInterval();
  127 + configRefreshTimerId = vertx.setPeriodic(
  128 + TimeUnit.SECONDS.toMillis(refreshInterval),
  129 + id -> refreshConfig()
  130 + );
  131 + running = true;
  132 + log.info("[start][IoT Modbus TCP 协议 {} 启动成功,serverId={}]", getId(), serverId);
  133 +
  134 + // 2. 启动下行消息订阅者
  135 + this.downstreamSubscriber.start();
  136 + } catch (Exception e) {
  137 + log.error("[start][IoT Modbus TCP 协议 {} 启动失败]", getId(), e);
  138 + // 启动失败时关闭资源
  139 + if (vertx != null) {
  140 + vertx.close();
  141 + }
  142 + throw e;
  143 + }
  144 + }
  145 +
  146 + @Override
  147 + public void stop() {
  148 + if (!running) {
  149 + return;
  150 + }
  151 + // 1. 停止下行消息订阅者
  152 + try {
  153 + downstreamSubscriber.stop();
  154 + log.info("[stop][IoT Modbus TCP 协议 {} 下行消息订阅者已停止]", getId());
  155 + } catch (Exception e) {
  156 + log.error("[stop][IoT Modbus TCP 协议 {} 下行消息订阅者停止失败]", getId(), e);
  157 + }
  158 +
  159 + // 2.1 取消配置刷新定时器
  160 + if (configRefreshTimerId != null) {
  161 + vertx.cancelTimer(configRefreshTimerId);
  162 + configRefreshTimerId = null;
  163 + }
  164 + // 2.2 停止轮询调度器
  165 + pollScheduler.stopAll();
  166 + log.info("[stop][IoT Modbus TCP 协议 {} 轮询调度器已停止]", getId());
  167 + // 2.3 关闭所有连接
  168 + connectionManager.closeAll();
  169 + log.info("[stop][IoT Modbus TCP 协议 {} 连接管理器已关闭]", getId());
  170 +
  171 + // 3. 关闭 Vert.x 实例
  172 + if (vertx != null) {
  173 + try {
  174 + vertx.close().result();
  175 + log.info("[stop][IoT Modbus TCP 协议 {} Vertx 已关闭]", getId());
  176 + } catch (Exception e) {
  177 + log.error("[stop][IoT Modbus TCP 协议 {} Vertx 关闭失败]", getId(), e);
  178 + }
  179 + }
  180 + running = false;
  181 + log.info("[stop][IoT Modbus TCP 协议 {} 已停止]", getId());
  182 + }
  183 +
  184 + /**
  185 + * 刷新配置
  186 + */
  187 + private synchronized void refreshConfig() {
  188 + try {
  189 + // 1. 从 biz 拉取最新配置
  190 + List<IotModbusDeviceConfigRespDTO> configs = configCacheService.refreshConfig();
  191 + log.debug("[refreshConfig][获取到 {} 个 Modbus 设备配置]", configs.size());
  192 +
  193 + // 2. 更新连接和轮询任务
  194 + for (IotModbusDeviceConfigRespDTO config : configs) {
  195 + try {
  196 + // 2.1 确保连接存在
  197 + connectionManager.ensureConnection(config);
  198 + // 2.2 更新轮询任务
  199 + pollScheduler.updatePolling(config);
  200 + } catch (Exception e) {
  201 + log.error("[refreshConfig][处理设备配置失败, deviceId={}]", config.getDeviceId(), e);
  202 + }
  203 + }
  204 +
  205 + // 3. 清理已删除设备的资源
  206 + configCacheService.cleanupRemovedDevices(configs, deviceId -> {
  207 + pollScheduler.stopPolling(deviceId);
  208 + connectionManager.removeDevice(deviceId);
  209 + });
  210 + } catch (Exception e) {
  211 + log.error("[refreshConfig][刷新配置失败]", e);
  212 + }
  213 + }
  214 +
  215 +}
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/IotModbusTcpUpstreamProtocol.java deleted
1 -package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp;  
2 -  
3 -import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO;  
4 -import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties;  
5 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService;  
6 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager;  
7 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpPollScheduler;  
8 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpUpstreamHandler;  
9 -import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;  
10 -import io.vertx.core.Vertx;  
11 -import jakarta.annotation.PostConstruct;  
12 -import jakarta.annotation.PreDestroy;  
13 -import lombok.Getter;  
14 -import lombok.RequiredArgsConstructor;  
15 -import lombok.extern.slf4j.Slf4j;  
16 -  
17 -import java.util.List;  
18 -import java.util.UUID;  
19 -import java.util.concurrent.TimeUnit;  
20 -  
21 -/**  
22 - * IoT Modbus TCP 上行协议:定时拉取配置、管理连接、调度轮询任务  
23 - *  
24 - * @author 芋道源码  
25 - */  
26 -@RequiredArgsConstructor  
27 -@Slf4j  
28 -public class IotModbusTcpUpstreamProtocol {  
29 -  
30 - private final IotGatewayProperties.ModbusTcpProperties modbusTcpProperties;  
31 - private final IotDeviceMessageService messageService;  
32 - private final IotModbusTcpConnectionManager connectionManager;  
33 - private final IotModbusTcpPollScheduler pollScheduler;  
34 - private final IotModbusTcpConfigCacheService configCacheService;  
35 - private final IotModbusTcpUpstreamHandler upstreamHandler;  
36 - private final Vertx vertx;  
37 -  
38 - /**  
39 - * 服务器 ID,用于标识当前网关实例  
40 - */  
41 - @Getter  
42 - private final String serverId = UUID.randomUUID().toString();  
43 -  
44 - /**  
45 - * 配置刷新定时器 ID  
46 - */  
47 - private Long configRefreshTimerId;  
48 -  
49 - @PostConstruct  
50 - public void start() {  
51 - log.info("[start][Modbus TCP 协议启动, serverId={}]", serverId);  
52 -  
53 - // 0. 设置 serverId 到上行处理器  
54 - upstreamHandler.setServerId(serverId);  
55 -  
56 - // 1. 首次加载配置  
57 - refreshConfig();  
58 -  
59 - // 2. 启动配置定时刷新  
60 - int refreshInterval = modbusTcpProperties.getConfigRefreshInterval();  
61 - configRefreshTimerId = vertx.setPeriodic(  
62 - TimeUnit.SECONDS.toMillis(refreshInterval),  
63 - id -> refreshConfig()  
64 - );  
65 - log.info("[start][配置刷新定时器已启动, 间隔={}秒]", refreshInterval);  
66 - }  
67 -  
68 - @PreDestroy  
69 - public void stop() {  
70 - log.info("[stop][Modbus TCP 协议停止]");  
71 -  
72 - // 1. 取消配置刷新定时器  
73 - if (configRefreshTimerId != null) {  
74 - vertx.cancelTimer(configRefreshTimerId);  
75 - }  
76 -  
77 - // 2. 停止轮询调度器  
78 - pollScheduler.stopAll();  
79 -  
80 - // 3. 关闭所有连接  
81 - connectionManager.closeAll();  
82 - }  
83 -  
84 - /**  
85 - * 刷新配置  
86 - */  
87 - private void refreshConfig() {  
88 - try {  
89 - // 1. 从 biz 拉取最新配置  
90 - List<IotModbusDeviceConfigRespDTO> configs = configCacheService.refreshConfig();  
91 - log.debug("[refreshConfig][获取到 {} 个 Modbus 设备配置]", configs.size());  
92 -  
93 - // 2. 更新连接和轮询任务  
94 - for (IotModbusDeviceConfigRespDTO config : configs) {  
95 - try {  
96 - // 2.1 确保连接存在  
97 - connectionManager.ensureConnection(config);  
98 - // 2.2 更新轮询任务  
99 - pollScheduler.updatePolling(config);  
100 - } catch (Exception e) {  
101 - log.error("[refreshConfig][处理设备配置失败, deviceId={}]", config.getDeviceId(), e);  
102 - }  
103 - }  
104 -  
105 - // 3. 清理已删除设备的资源  
106 - configCacheService.cleanupRemovedDevices(configs, deviceId -> {  
107 - pollScheduler.stopPolling(deviceId);  
108 - connectionManager.removeDevice(deviceId);  
109 - });  
110 - } catch (Exception e) {  
111 - log.error("[refreshConfig][刷新配置失败]", e);  
112 - }  
113 - }  
114 -  
115 -}  
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/router/IotModbusTcpDownstreamHandler.java renamed to yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/handler/downstream/IotModbusTcpDownstreamHandler.java
1 -package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router; 1 +package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.downstream;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO; 4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO;
5 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusPointRespDTO; 5 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusPointRespDTO;
  6 +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
6 import cn.iocoder.yudao.module.iot.core.enums.IotModbusFunctionCodeEnum; 7 import cn.iocoder.yudao.module.iot.core.enums.IotModbusFunctionCodeEnum;
7 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 8 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
8 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;  
9 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient; 9 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient;
  10 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;
10 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService; 11 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConfigCacheService;
11 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager; 12 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager.IotModbusTcpConnectionManager;
12 import lombok.RequiredArgsConstructor; 13 import lombok.RequiredArgsConstructor;
@@ -16,7 +17,7 @@ import java.util.Map; @@ -16,7 +17,7 @@ import java.util.Map;
16 17
17 /** 18 /**
18 * IoT Modbus TCP 下行消息处理器 19 * IoT Modbus TCP 下行消息处理器
19 - * 20 + * <p>
20 * 负责: 21 * 负责:
21 * 1. 处理下行消息(如属性设置 thing.service.property.set) 22 * 1. 处理下行消息(如属性设置 thing.service.property.set)
22 * 2. 执行 Modbus 写入操作 23 * 2. 执行 Modbus 写入操作
@@ -38,8 +39,7 @@ public class IotModbusTcpDownstreamHandler { @@ -38,8 +39,7 @@ public class IotModbusTcpDownstreamHandler {
38 @SuppressWarnings("unchecked") 39 @SuppressWarnings("unchecked")
39 public void handle(IotDeviceMessage message) { 40 public void handle(IotDeviceMessage message) {
40 // 1.1 检查是否是属性设置消息 41 // 1.1 检查是否是属性设置消息
41 - // TODO @AI:要使用枚举  
42 - if (!"thing.service.property.set".equals(message.getMethod())) { 42 + if (!IotDeviceMessageMethodEnum.PROPERTY_SET.getMethod().equals(message.getMethod())) {
43 log.debug("[handle][忽略非属性设置消息: {}]", message.getMethod()); 43 log.debug("[handle][忽略非属性设置消息: {}]", message.getMethod());
44 return; 44 return;
45 } 45 }
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/IotModbusTcpDownstreamSubscriber.java renamed to yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/handler/downstream/IotModbusTcpDownstreamSubscriber.java
1 -package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp; 1 +package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.downstream;
2 2
3 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; 3 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus;
4 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber; 4 import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber;
5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 6 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
7 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpDownstreamHandler;  
8 -import jakarta.annotation.PostConstruct; 7 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.IotModbusTcpProtocol;
9 import lombok.RequiredArgsConstructor; 8 import lombok.RequiredArgsConstructor;
10 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
11 10
@@ -18,19 +17,29 @@ import lombok.extern.slf4j.Slf4j; @@ -18,19 +17,29 @@ import lombok.extern.slf4j.Slf4j;
18 @Slf4j 17 @Slf4j
19 public class IotModbusTcpDownstreamSubscriber implements IotMessageSubscriber<IotDeviceMessage> { 18 public class IotModbusTcpDownstreamSubscriber implements IotMessageSubscriber<IotDeviceMessage> {
20 19
21 - private final IotModbusTcpUpstreamProtocol upstreamProtocol; 20 + private final IotModbusTcpProtocol protocol;
22 private final IotModbusTcpDownstreamHandler downstreamHandler; 21 private final IotModbusTcpDownstreamHandler downstreamHandler;
23 private final IotMessageBus messageBus; 22 private final IotMessageBus messageBus;
24 23
25 - @PostConstruct  
26 - public void subscribe() { 24 + /**
  25 + * 启动订阅
  26 + */
  27 + public void start() {
27 messageBus.register(this); 28 messageBus.register(this);
28 - log.info("[subscribe][Modbus TCP 下行消息订阅器已启动, topic={}]", getTopic()); 29 + log.info("[start][Modbus TCP 下行消息订阅器已启动, topic={}]", getTopic());
  30 + }
  31 +
  32 + /**
  33 + * 停止订阅
  34 + */
  35 + public void stop() {
  36 + messageBus.unregister(this);
  37 + log.info("[stop][Modbus TCP 下行消息订阅器已停止]");
29 } 38 }
30 39
31 @Override 40 @Override
32 public String getTopic() { 41 public String getTopic() {
33 - return IotDeviceMessageUtils.buildMessageBusGatewayDeviceMessageTopic(upstreamProtocol.getServerId()); 42 + return IotDeviceMessageUtils.buildMessageBusGatewayDeviceMessageTopic(protocol.getServerId());
34 } 43 }
35 44
36 @Override 45 @Override
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/router/IotModbusTcpUpstreamHandler.java renamed to yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/handler/upstream/IotModbusTcpUpstreamHandler.java
1 -package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router; 1 +package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.upstream;
2 2
3 import cn.hutool.core.map.MapUtil; 3 import cn.hutool.core.map.MapUtil;
4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO; 4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO;
@@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
7 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 7 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
8 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter; 8 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.codec.IotModbusDataConverter;
9 import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService; 9 import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
10 -import lombok.Setter;  
11 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
12 11
13 import java.util.Map; 12 import java.util.Map;
@@ -22,14 +21,14 @@ public class IotModbusTcpUpstreamHandler { @@ -22,14 +21,14 @@ public class IotModbusTcpUpstreamHandler {
22 21
23 private final IotDeviceMessageService messageService; 22 private final IotDeviceMessageService messageService;
24 private final IotModbusDataConverter dataConverter; 23 private final IotModbusDataConverter dataConverter;
25 -  
26 - @Setter  
27 - private String serverId; 24 + private final String serverId;
28 25
29 public IotModbusTcpUpstreamHandler(IotDeviceMessageService messageService, 26 public IotModbusTcpUpstreamHandler(IotDeviceMessageService messageService,
30 - IotModbusDataConverter dataConverter) { 27 + IotModbusDataConverter dataConverter,
  28 + String serverId) {
31 this.messageService = messageService; 29 this.messageService = messageService;
32 this.dataConverter = dataConverter; 30 this.dataConverter = dataConverter;
  31 + this.serverId = serverId;
33 } 32 }
34 33
35 /** 34 /**
@@ -40,8 +39,8 @@ public class IotModbusTcpUpstreamHandler { @@ -40,8 +39,8 @@ public class IotModbusTcpUpstreamHandler {
40 * @param rawValue 原始值(int 数组) 39 * @param rawValue 原始值(int 数组)
41 */ 40 */
42 public void handleReadResult(IotModbusDeviceConfigRespDTO config, 41 public void handleReadResult(IotModbusDeviceConfigRespDTO config,
43 - IotModbusPointRespDTO point,  
44 - int[] rawValue) { 42 + IotModbusPointRespDTO point,
  43 + int[] rawValue) {
45 try { 44 try {
46 // 1.1 转换原始值为物模型属性值 45 // 1.1 转换原始值为物模型属性值
47 Object convertedValue = dataConverter.convertToPropertyValue(rawValue, point); 46 Object convertedValue = dataConverter.convertToPropertyValue(rawValue, point);
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbustcp/manager/IotModbusTcpPollScheduler.java
@@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager; @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.manager;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO; 4 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusDeviceConfigRespDTO;
5 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusPointRespDTO; 5 import cn.iocoder.yudao.module.iot.core.biz.dto.IotModbusPointRespDTO;
6 -import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.router.IotModbusTcpUpstreamHandler;  
7 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient; 6 import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.client.IotModbusTcpClient;
  7 +import cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp.handler.upstream.IotModbusTcpUpstreamHandler;
8 import io.vertx.core.Vertx; 8 import io.vertx.core.Vertx;
9 import lombok.AllArgsConstructor; 9 import lombok.AllArgsConstructor;
10 import lombok.Data; 10 import lombok.Data;
yudao-module-iot/yudao-module-iot-gateway/src/main/resources/application.yaml
@@ -51,8 +51,6 @@ yudao: @@ -51,8 +51,6 @@ yudao:
51 protocol: http 51 protocol: http
52 port: 8092 52 port: 8092
53 enabled: false 53 enabled: false
54 - http:  
55 - ssl-enabled: false  
56 # ==================================== 54 # ====================================
57 # 针对引入的 TCP 组件的配置 55 # 针对引入的 TCP 组件的配置
58 # ==================================== 56 # ====================================
@@ -64,7 +62,6 @@ yudao: @@ -64,7 +62,6 @@ yudao:
64 tcp: 62 tcp:
65 max-connections: 1000 63 max-connections: 1000
66 keep-alive-timeout-ms: 30000 64 keep-alive-timeout-ms: 30000
67 - ssl-enabled: false  
68 codec: 65 codec:
69 type: delimiter # 拆包类型:length_field / delimiter / fixed_length 66 type: delimiter # 拆包类型:length_field / delimiter / fixed_length
70 delimiter: "\\n" # 分隔符(支持转义:\\n=换行, \\r=回车, \\t=制表符) 67 delimiter: "\\n" # 分隔符(支持转义:\\n=换行, \\r=回车, \\t=制表符)
@@ -101,7 +98,6 @@ yudao: @@ -101,7 +98,6 @@ yudao:
101 max-message-size: 65536 # 最大消息大小(字节,默认 64KB) 98 max-message-size: 65536 # 最大消息大小(字节,默认 64KB)
102 max-frame-size: 65536 # 最大帧大小(字节,默认 64KB) 99 max-frame-size: 65536 # 最大帧大小(字节,默认 64KB)
103 idle-timeout-seconds: 60 # 空闲超时时间(秒,默认 60) 100 idle-timeout-seconds: 60 # 空闲超时时间(秒,默认 60)
104 - ssl-enabled: false # 是否启用 SSL(wss://)  
105 # ==================================== 101 # ====================================
106 # 针对引入的 CoAP 组件的配置 102 # 针对引入的 CoAP 组件的配置
107 # ==================================== 103 # ====================================
@@ -117,14 +113,13 @@ yudao: @@ -117,14 +113,13 @@ yudao:
117 # 针对引入的 MQTT 组件的配置 113 # 针对引入的 MQTT 组件的配置
118 # ==================================== 114 # ====================================
119 - id: mqtt-json 115 - id: mqtt-json
120 - enabled: true 116 + enabled: false
121 protocol: mqtt 117 protocol: mqtt
122 port: 1883 118 port: 1883
123 serialize: json 119 serialize: json
124 mqtt: 120 mqtt:
125 max-message-size: 8192 # 最大消息大小(字节) 121 max-message-size: 8192 # 最大消息大小(字节)
126 connect-timeout-seconds: 60 # 连接超时时间(秒) 122 connect-timeout-seconds: 60 # 连接超时时间(秒)
127 - ssl-enabled: false # 是否启用 SSL  
128 # ==================================== 123 # ====================================
129 # 针对引入的 EMQX 组件的配置 124 # 针对引入的 EMQX 组件的配置
130 # ==================================== 125 # ====================================
@@ -168,43 +163,15 @@ yudao: @@ -168,43 +163,15 @@ yudao:
168 key-store-password: "your-keystore-password" # 客户端证书库密码 163 key-store-password: "your-keystore-password" # 客户端证书库密码
169 trust-store-path: "classpath:certs/trust.jks" # 信任的 CA 证书库路径 164 trust-store-path: "classpath:certs/trust.jks" # 信任的 CA 证书库路径
170 trust-store-password: "your-truststore-password" # 信任的 CA 证书库密码 165 trust-store-password: "your-truststore-password" # 信任的 CA 证书库密码
171 - http-port: 8090 # MQTT HTTP 服务端口  
172 - mqtt-host: 127.0.0.1 # MQTT Broker 地址  
173 - mqtt-port: 1883 # MQTT Broker 端口  
174 - mqtt-username: admin # MQTT 用户名  
175 - mqtt-password: public # MQTT 密码  
176 - mqtt-client-id: iot-gateway-mqtt # MQTT 客户端 ID  
177 - mqtt-ssl: false # 是否开启 SSL  
178 - mqtt-topics:  
179 - - "/sys/#" # 系统主题  
180 - clean-session: true # 是否启用 Clean Session (默认: true)  
181 - keep-alive-interval-seconds: 60 # 心跳间隔,单位秒 (默认: 60)  
182 - max-inflight-queue: 10000 # 最大飞行消息队列,单位:条  
183 - connect-timeout-seconds: 10 # 连接超时,单位:秒  
184 - # 是否信任所有 SSL 证书 (默认: false)。警告:生产环境必须为 false!  
185 - # 仅在开发环境或内网测试时,如果使用了自签名证书,可以临时设置为 true  
186 - trust-all: true # 在 dev 环境可以设为 true  
187 - # 遗嘱消息配置 (用于网关异常下线时通知其他系统)  
188 - will:  
189 - enabled: true # 生产环境强烈建议开启  
190 - topic: "gateway/status/${yudao.iot.gateway.emqx.mqtt-client-id}" # 遗嘱消息主题  
191 - payload: "offline" # 遗嘱消息负载  
192 - qos: 1 # 遗嘱消息 QoS  
193 - retain: true # 遗嘱消息是否保留  
194 - # 高级 SSL/TLS 配置 (当 trust-all: false 且 mqtt-ssl: true 时生效)  
195 - ssl-options:  
196 - key-store-path: "classpath:certs/client.jks" # 客户端证书库路径  
197 - key-store-password: "your-keystore-password" # 客户端证书库密码  
198 - trust-store-path: "classpath:certs/trust.jks" # 信任的 CA 证书库路径  
199 - trust-store-password: "your-truststore-password" # 信任的 CA 证书库密码  
200 # ==================================== 166 # ====================================
201 - # 针对引入的 MQTT 组件的配置 167 + # 针对引入的 Modbus TCP 组件的配置
202 # ==================================== 168 # ====================================
203 - # 协议配置(旧版,保持兼容)  
204 - protocol:  
205 - modbus-tcp: 169 + - id: modbus-tcp-1
206 enabled: true 170 enabled: true
207 - config-refresh-interval: 30 # 配置刷新间隔(秒) 171 + protocol: modbus_tcp
  172 + port: 502
  173 + modbus-tcp:
  174 + config-refresh-interval: 30 # 配置刷新间隔(秒)
208 175
209 --- #################### 日志相关配置 #################### 176 --- #################### 日志相关配置 ####################
210 177
@@ -226,6 +193,7 @@ logging: @@ -226,6 +193,7 @@ logging:
226 cn.iocoder.yudao.module.iot.gateway.protocol.mqtt: DEBUG 193 cn.iocoder.yudao.module.iot.gateway.protocol.mqtt: DEBUG
227 cn.iocoder.yudao.module.iot.gateway.protocol.coap: DEBUG 194 cn.iocoder.yudao.module.iot.gateway.protocol.coap: DEBUG
228 cn.iocoder.yudao.module.iot.gateway.protocol.websocket: DEBUG 195 cn.iocoder.yudao.module.iot.gateway.protocol.websocket: DEBUG
  196 + cn.iocoder.yudao.module.iot.gateway.protocol.modbustcp: DEBUG
229 # 根日志级别 197 # 根日志级别
230 root: INFO 198 root: INFO
231 199