Files
railwaysystem/RuoYi-Vue/docs/mqtt_removal_plan.md
T
buliping 1def568f24 refactor(iot): 移除 MQTT 传输层,仅保留设备开放接口与门禁写操作策略
- 依赖:删除根 pom 的 paho.version 与 org.eclipse.paho.client.mqttv3 依赖声明,
  同步移除 ruoyi-iot 模块中的 Paho 依赖,模块描述改为“iot设备数据与开放接口”
- MQTT 协议栈整体删除:IotMqttConfig、IotMqttProperties、MqttClientManager、
  MqttMessageDispatcher、MqttCallbackHandler、MqttConnectionCallback、
  IMqttMessageListener、MqttMessageDTO、MqttPublishRequest、MqttMessageEvent、
  IMqttService/MqttServiceImpl、IotMqttController,以及 lock 侧 topic 订阅与
  LockMessageListener、AccessRecordHandler、CommandRespHandler、
  GatewayOnlineHandler、LockSignalHandler
- MQTT 报文留痕链路删除:LockMqttLog 实体、LockMqttLogMapper(+XML)、
  ILockMqttLogService/LockMqttLogServiceImpl、LockMqttLogController,
  以及对应的前端页面 build_ui/src/views/iot/mqttlog 与 API build_ui/src/api/iot/mqttlog.js
- 命令下发改为仅落库:LockCommandServiceImpl 派发时直接置 TRANSPORT_DISABLED 失败,
  retryPending 返回 0;删除 GatewayOfflineCheckTask、LockCommandRetryTask、
  LockDeviceOfflineCheckTask 等依赖 MQTT 的补偿与离线检查定时任务
- 保留与传输无关的门禁写操作策略:新增 IotLockSecurityProperties(iot.lock-security),
  RealIotSecurityGate 及其测试改用该配置类
- 配置与调用处清理:application*.yml 中 iot.mqtt 段迁移为 iot.lock-security,
  删除 broker-url/client-id/username/password/topics/will/qos 等连接参数,
  修正 iot.face 环境标识注释引用;QA 工具启动参数改用 --iot.lock-security.*,
  并移除 browser_regression.js 的 mqttlog 路由
- 测试同步:删除依赖 MQTT 与传输层的 CommandRespHandlerMockTest、
  Round5sEgressIsolationTest、Round5sExecutionIntegrationTest、
  Round5v4BrowserFixture、Round5v4KingbaseIntegrationTest;
  更新 RealIotSecurityGateTest、FaceExtractClientMockTest、
  TrainIotLockAuthBridgeMockTest

说明:数据库侧 lock_mqtt_log 表结构与历史验收文档保留,未做数据迁移;
前端若仍配置了“MQTT报文日志”菜单,需在后台菜单管理中一并移除。
2026-11-10 16:06:23 +08:00

12 KiB
Raw Blame History

从项目移除 MQTT——文件级改造清单

适用范围:RuoYi-Vue(railwaysystem)全部模块 方案定位:方案 A(推荐)——只拆除"MQTT 传输 + 订阅回调 + 调度 + 留痕",保留数据层、协议构造层与 HTTP 能力 红线约束:报到机人脸采集与门锁入住 HTTP 链路必须完整保留 编制时间:2026-11-10


目录


0. 关键前提

不能直接删除 ruoyi-iot 模块。 该模块除 MQTT 外还承载三类被强依赖的能力:

能力 被谁依赖 说明
报到机 HTTP(人脸采集 / 门锁入住) ruoyi-admin 控制器直接 import com.ruoyi.iot.lock.*(LockDeviceMapper、ILockAuthService、LockAuth)
人脸特征提取(HTTP 调外部服务) ruoyi-train TrainStudentServiceImpl 使用 FaceExtractClient、LockFace、LockAuthMapper
门锁主数据 + HTTP 开放接口 ruoyi-admin、ruoyi-train 设备/网关/分组/授权/开门记录 CRUD、/openapi/**

结论:采用方案 A——仅移除 MQTT 传输侧,保留数据层、协议构造层、开放接口。授权/设备/网关三个业务服务无需改动。


1. 严禁删除、严禁修改的保留项

1.1 报到机 HTTP 链路(红线)

文件 说明
ruoyi-admin/.../controller/api/TrainRegisterApiController.java 人脸采集、门锁入住(callStayCheckin)、报到重置;方案 A 下零改动
ruoyi-admin/.../controller/api/TrainFaceApiController.java 被报到机控制器复用(deleteEmployee 解绑人脸)
ruoyi-train/.../integration/lock/client/TrainLockStayApiClient.java HTTP 门锁入住/退宿开放平台客户端
ruoyi-train/.../integration/lock/dto/LockStayCheckinResult.java 入住结果 DTO
ruoyi-train/.../integration/lock/dto/LockAuthBridgeResult.java 授权桥接结果 DTO

TrainRegisterApiController 依赖的 ILockAuthService、LockDeviceMapper 在本方案中均保留,因此该文件不需要任何改动。

1.2 人脸能力(HTTP,非 MQTT)

ruoyi-iot/.../lock/remote/FaceExtractClient.java
ruoyi-iot/.../config/FaceExtractProperties.java
ruoyi-iot/.../lock/domain/LockFace.java
ruoyi-iot/.../lock/mapper/LockFaceMapper.java  (+ resources/mapper/lock/LockFaceMapper.xml)
ruoyi-iot/.../lock/service/ILockFaceService.java
ruoyi-iot/.../lock/service/impl/LockFaceServiceImpl.java
ruoyi-iot/.../lock/controller/LockFaceController.java
ruoyi-train/.../service/impl/TrainStudentServiceImpl.java
ruoyi-train/.../mapper/TrainStudentMapper.java

1.3 门锁主数据与 DB 层

lock/domain/LockDevice.java  LockGateway.java  LockGroup.java  LockAuth.java
            LockAccessLog.java  ExecutionRecord.java  LockServiceConfig.java
lock/mapper/LockDeviceMapper.java  LockGatewayMapper.java  LockGroupMapper.java
            LockAuthMapper.java  LockAccessLogMapper.java  LockServiceConfigMapper.java
resources/mapper/lock/Lock{Device,Gateway,Group,Auth,AccessLog,ServiceConfig}Mapper.xml
lock/service/ILock{Auth,Device,Gateway,Group,AccessLog,ServiceConfig}Service.java + impl
lock/controller/Lock{Auth,Device,Gateway,Group,AccessLog,ServiceConfig}Controller.java

三个业务实现类(LockAuthServiceImpl、LockDeviceServiceImpl、LockGatewayServiceImpl)只间接依赖命令服务,本方案中不改。

1.4 状态机与协议构造层

lock/security/RealIotSecurityGate.java      (无任何 MQTT 引用,被 train 授权桥接直接用)
lock/security/ExecutionStates.java
lock/service/LockExecutionTransactions.java
lock/LockConstants.java
lock/protocol/YdlinkCodec.java  YdlinkFrameDTO.java  YdlinkOp.java
             YdlinkTopicBuilder.java  YdlinkTopicDTO.java  YdlinkTopicType.java
             LockAuthPayloadFactory.java

原因:上述协议类被 LockAuthServiceImpl、LockDeviceServiceImpl、LockGatewayServiceImpl 用于生成 lock_command.payload/topic 并落库(outbox)。删除会连带 4 个业务类和大量测试改动,违背最小改动原则。

1.5 HTTP 开放接口

ruoyi-iot/.../openapi/**(OpenAuthApiController、OpenFaceApiController、OpenQueryApiController、
                          OpenApiAuthFilter、OpenApiProperties、Open*Request)

1.6 容易误删的隐形依赖

文件 为什么不能删
ruoyi-iot/.../lock/task/LockScheduleConfig.java 全项目唯一的 @EnableScheduling;ruoyi-train 的 DmsOperationPoller(@Scheduled)依赖它,删除会静默停掉 DMS 轮询

2. 需删除的文件(36 个)

2.1 MQTT 连接与传输核心(13)

文件 删除理由
config/IotMqttConfig.java MQTT 客户端 Bean 装配与生命周期初始化
config/IotMqttProperties.java iot.mqtt.* 全部配置项
core/MqttClientManager.java 连接、重连、健康检查、订阅恢复、发布
core/MqttCallbackHandler.java Paho 回调入口
core/MqttConnectionCallback.java 连接状态回调接口
core/MqttMessageDispatcher.java 上行消息分发
core/IMqttMessageListener.java 业务监听器 SPI
domain/MqttMessageDTO.java 消息载体
domain/MqttPublishRequest.java 发布请求 DTO
event/MqttMessageEvent.java 消息事件(无其他监听者)
service/IMqttService.java 发布/订阅抽象
service/impl/MqttServiceImpl.java 唯一实现
controller/IotMqttController.java `/iot/mqtt/status

2.2 订阅与上行回调处理(6)

文件 删除理由
lock/mqtt/LockTopicSubscriber.java 启动订阅 5 个 ydlink 主题(ApplicationRunner)
lock/mqtt/LockMessageListener.java 消息路由 + 报文留痕
lock/mqtt/handler/GatewayOnlineHandler.java 上下线回调
lock/mqtt/handler/CommandRespHandler.java 三类回执处理
lock/mqtt/handler/AccessRecordHandler.java 开门记录回调
lock/mqtt/handler/LockSignalHandler.java 信号/电量回调

2.3 MQTT 相关调度任务(3)

文件 删除理由
lock/task/LockCommandRetryTask.java 依赖 retryPending → dispatch → publish,无传输后无意义
lock/task/GatewayOfflineCheckTask.java 依据 MQTT 心跳判定离线,移除后会误判全员离线
lock/task/LockDeviceOfflineCheckTask.java 同上

2.4 报文留痕(6)

lock/domain/LockMqttLog.java
lock/mapper/LockMqttLogMapper.java
resources/mapper/lock/LockMqttLogMapper.xml
lock/service/ILockMqttLogService.java
lock/service/impl/LockMqttLogServiceImpl.java
lock/controller/LockMqttLogController.java

DB 表 lock_mqtt_log 在仓库内无 DDL,可保留空表或手工 DROP(不在本次代码范围)。

2.5 QA 模拟(1)

ruoyi-admin/.../controller/tool/QaMockMqttApiController.java

2.6 测试(3)

ruoyi-iot/src/test/.../lock/mqtt/handler/CommandRespHandlerMockTest.java
ruoyi-iot/src/test/.../lock/security/Round5sExecutionIntegrationTest.java   (依赖 MqttClientManager/IMqttService)
ruoyi-iot/src/test/.../lock/security/Round5sEgressIsolationTest.java        (以传输层断言为主)

3. 需修改的文件(7 个)

3.1 ruoyi-iot/.../lock/service/impl/LockCommandServiceImpl.java(唯一业务改动)

点位 改动 目的
第 18 行 删除 import ...IMqttService 解除传输依赖
第 37 行 删除 @Lazy @Autowired IMqttService mqttService 同上
留痕块(约 90-115 行) 删除 mqttLogMapper 字段与 writeMqttLog 逻辑 留痕层已删除
dispatch() 169-174 行 去掉 isConnected() 判断,改为直接置 STATUS_FAIL + errorMsg="TRANSPORT_DISABLED" 并返回 null 保留断连语义,避免上游状态悬挂
dispatch() 180-203 行 删除 publishCommand() 与 AWAITING_ACK 迁移分支,改为 return false 移除发布逻辑
retryPending() 206-210 行 改为 return 0(或随 RetryTask 一并删除) 无补偿下发

替代方案:若完全不想碰业务文件,可保留 IMqttService/MqttServiceImpl 作为空实现,但 MQTT 依赖仍在,不满足"移除"目标。二者取其一。

3.2 ruoyi-iot/pom.xml

  • 删除 org.eclipse.paho:org.eclipse.paho.client.mqttv3 依赖(第 22-26 行)
  • <description> 由"iot设备接入(MQTT)"改为"iot设备数据与开放接口"

3.3 根 pom.xml

  • 删除 paho.version 属性
  • 删除 dependencyManagement 中 Paho 条目(第 148-153 行)

3.4 ruoyi-admin/src/main/resources/application.yml

  • 整段删除 iot.mqtt(第 195-259 行:enabled / mock / broker-url / username / topics / will 等)
  • 保留 iot: 下其他节点:hmac、openapi、face、lock_endpoint、api_key、avatar_profile、face_api_key

3.5 三个环境变体配置

application_localhost.yml
application_localhost_24.yml
application_localhost_230.yml

同样只删 mqtt: 子树,保留其余 iot.*。

3.6 ruoyi-iot/src/test/.../lock/security/RealIotSecurityGateTest.java

  • 删除使用 new MqttClientManager(p, null).publish(...) 的断言(约第 38 行)
  • 保留其余门禁策略断言(该类本身保留)

3.7 文档(可选)

docs/mqtt_usage_and_status.md 标注"已移除",或移入归档目录。


4. 改造后行为说明

场景 改造后行为
应用启动 不再创建 MQTT 连接、不再订阅主题、无 iot-mqtt-health 线程、无连接失败日志
业务触发授权/开关锁 仍生成 lock_command 记录,但状态直接落 FAIL / TRANSPORT_DISABLED,不产生任何网络请求
报到机人脸采集 完全不变(HTTP + 本地文件 + 人脸服务 HTTP)
报到机门锁入住 完全不变(TrainLockStayApiClient HTTP)
管理端门锁/网关/分组/人脸页面 查询与维护功能保留;"下发/远程控制"类操作返回失败提示
DMS 轮询任务 正常(LockScheduleConfig 保留)

5. 方案 B(彻底清理,仅供评估)

若要求连同 lock_command outbox 一并移除,需追加修改:

  • LockAuthServiceImpl、LockDeviceServiceImpl、LockGatewayServiceImpl:删除命令构造与 commandService.send(...)
  • LockCommandServiceImpl、ILockCommandService、LockCommand、LockCommandMapper(+XML)、LockCommandController:整体删除
  • RealIotSecurityGate:删除 requireDispatchAllowed / payload 校验分支
  • ruoyi-train/.../TrainIotLockAuthBridgeServiceImpl:改为仅维护授权记录,不再生成命令
  • 相关测试:Round5v4KingbaseIntegrationTest、Round5v4BrowserFixture、TrainIotLockAuthBridgeMockTest 需重写
  • protocol/** 可随之删除

风险:触及 10+ 业务文件与 5+ 测试,且与保留链路相交(LockAuthMapper 仍在授权桥接中使用),回归成本高。


6. 执行顺序建议

  1. 先改 LockCommandServiceImpl(去 IMqttService、去留痕)——此时传输层仍存在但不被引用
  2. 再删 2.2 订阅/回调、2.3 调度、2.4 留痕、2.1 传输核心、2.5 QA
  3. 删依赖(3.2、3.3)与配置(3.4、3.5)
  4. 清理测试(2.6、3.6)
  5. 验证:
    mvn -o -pl ruoyi-iot,ruoyi-train,ruoyi-admin -am test-compile
    
    启动冒烟后回归三条 HTTP 链路:人脸上传 → 门锁入住 → 报到重置

再次提醒:LockScheduleConfig、protocol/**、RealIotSecurityGate、openapi/**、FaceExtractClient、Lock*Mapper 六类文件不在删除范围;删除会直接破坏保留功能或导致其它模块编译失败。


文档结束。