文章目录
- 本地FastDDS+远端MQTT转发(多主机数据隔离)架构设计与落地
- 一、架构核心设计(贴合你的多主机/Qt+C++场景)
- 1. 整体架构图(文字版)
- 2. 核心模块职责
- 二、数据隔离的双层实现(核心需求落地)
- 1. 本地层:FastDDS Domain ID 物理隔离
- 2. 远端层:MQTT主题+ACL 逻辑隔离
- (1)MQTT主题命名规则(统一格式,强制隔离)
- (2)MQTT Broker ACL权限(强化隔离)
- 三、架构优缺点
- 1. 核心优势
- 2. 潜在劣势与解决方案
- 四、Qt+C++落地实现要点(核心代码框架)
- 1. 中转站核心代码(FastDDS接收+MQTT转发)
- 2. 本地EXE代码(仅需FastDDS,无需关心MQTT)
- 3. 配置文件(config.ini,跨主机仅需修改此文件)
- 五、最终建议
- 1. 架构选型结论
- 2. 落地优先级
- 3. 替代方案对比(仅作参考)
本地FastDDS+远端MQTT转发(多主机数据隔离)架构设计与落地
一、架构核心设计(贴合你的多主机/Qt+C++场景)
该架构的核心是**“单主机FastDDS域隔离 + 中转站统一转发 + MQTT主题/ACL远端隔离”**,每台主机部署一个“FastDDS-MQTT中转站”,作为本地FastDDS和远端MQTT的唯一桥梁,既保留FastDDS本地自动配置的优势,又通过MQTT实现跨主机/远端通信,同时保障多主机数据隔离。
1. 整体架构图(文字版)
┌────────────────────────────────────────────── 主机A ──────────────────────────────────────────────┐ │ ┌─────────┐ ┌─────────┐ ┌──────────────────────────────────────────────┐ │ │ │本地EXE 1│ │本地EXE 2│ │ FastDDS-MQTT 中转站 │ │ │ │(FastDDS)│◄──►│(FastDDS)│◄──►│ [FastDDS模块] [MQTT模块] [隔离管控] │◄─────┐ │ │ └─────────┘ └─────────┘ └──────────────────────────────────────────────┘ │ │ │ ▲ │ │ │ │(本地 FastDDS,Domain ID = 100) │ │ └────────────────────────────────────┴────────────────────────────────────────────────┘ │ │ ┌────────────────────────────────────────────── 主机B ──────────────────────────────────────────────┐ │ ┌─────────┐ ┌─────────┐ ┌──────────────────────────────────────────────┐ │ │ │本地EXE 1│ │本地EXE 2│ │ FastDDS-MQTT 中转站 │ │ │ │(FastDDS)│◄──►│(FastDDS)│◄──►│ [FastDDS模块] [MQTT模块] [隔离管控] │◄─────┐ │ │ └─────────┘ └─────────┘ └──────────────────────────────────────────────┘ │ │ │ ▲ │ │ │ │(本地 FastDDS,Domain ID = 101) │ │ └────────────────────────────────────┴────────────────────────────────────────────────┘ │ │ ▼ ▼ ┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 远端 MQTT Broker(EMQ X / 阿里云 IoT) │ │ (主题隔离 + ACL 权限,实现多主机数据隔离) │ └───────────────────────────────────────────────────────────────────────────────────────────────────┘2. 核心模块职责
| 模块 | 核心职责 |
|---|---|
| 本地EXE(FastDDS) | 仅接入本机专属FastDDS域,发布/订阅数据(无需关心MQTT),享受FastDDS自动发现/配置的优势; |
| 主机内FastDDS域 | 每台主机分配唯一Domain ID(如主机A=100,主机B=101),本地FastDDS仅发现同域节点,实现本地数据物理隔离; |
| FastDDS-MQTT中转站 | 1. 本机FastDDS域的“超级节点”:订阅本地所有FastDDS Topic,接收所有EXE数据; 2. 数据转换:将FastDDS的CDR格式转为MQTT可传输的ProtoBuf/JSON; 3. MQTT转发:按“主机标识+Topic”规则发布到远端Broker; 4. 反向转发:接收远端MQTT数据,转换为FastDDS格式,发布到本机域; 5. 隔离管控:严格按权限订阅/发布MQTT主题,禁止跨主机越权; |
| 远端MQTT Broker | 1. 主题隔离:按“主机标识”划分MQTT主题空间; 2. ACL权限:限制每个中转站仅能访问自身主机的主题; |
二、数据隔离的双层实现(核心需求落地)
多主机数据隔离需从“本地物理隔离”和“远端逻辑隔离”两层入手,缺一不可:
1. 本地层:FastDDS Domain ID 物理隔离
- 核心逻辑:FastDDS的Domain ID是节点分组的核心标识,不同Domain ID的节点无法互相发现、通信,实现“本机数据不跨域”;
- 落地配置:
- 为每台主机分配唯一的Domain ID(范围0-232,避免冲突),写入中转站的配置文件(如
domain_id=100); - 本地所有EXE和中转站均使用该Domain ID创建FastDDS参与者,跨主机的FastDDS数据完全隔离,即使网络互通也无法访问;
- 中转站是本机域内唯一能与MQTT交互的节点,本地EXE无MQTT权限,杜绝EXE直接访问远端数据。
- 为每台主机分配唯一的Domain ID(范围0-232,避免冲突),写入中转站的配置文件(如
2. 远端层:MQTT主题+ACL 逻辑隔离
(1)MQTT主题命名规则(统一格式,强制隔离)
定义全局唯一的主题格式,将“主机标识”作为主题前缀,确保不同主机的数据不会混流:
/host/{主机唯一标识}/{数据类型}/{FastDDS Topic名}- 示例:
- 主机A(标识
device001)的北斗数据:/host/device001/sensor/BeidouData; - 主机B(标识
device002)的USBL数据:/host/device002/sensor/USBLData;
- 主机A(标识
- 中转站自动拼接规则:读取本机配置的
host_id,将本地FastDDS Topic转换为上述MQTT主题,无需手动修改代码。
(2)MQTT Broker ACL权限(强化隔离)
在MQTT Broker(推荐EMQ X)中配置ACL规则,限制每个中转站的MQTT客户端仅能访问自身主机的主题:
# EMQ X ACL配置示例 allow device001 publish /host/device001/# allow device001 subscribe /host/device001/# allow device002 publish /host/device002/# allow device002 subscribe /host/device002/# deny all publish # deny all subscribe #- 效果:主机A的中转站只能发布/订阅
/host/device001/下的主题,无法访问主机B的主题,即使知道主题名也会被Broker拒绝。
三、架构优缺点
1. 核心优势
| 优势维度 | 具体价值 |
|---|---|
| 本地通信体验 | 完全复用FastDDS的自动发现/配置/序列化,本地EXE仅需订阅Topic即可通信,无需手动配置地址/序列化; |
| 数据隔离安全性 | 双层隔离(Domain ID物理隔离+MQTT主题/ACL逻辑隔离),多主机数据完全隔离,避免越权访问; |
| 远端通信适配性 | MQTT穿透性强(跨网段/公网/防火墙),部署成本远低于FastDDS的跨网段DS服务器; |
| Qt+C++适配性 | FastDDS和Qt MQTT模块(Qt5.10+原生支持)均可集成到Qt项目,跨平台(Win/Linux/macOS)编译; |
| 灵活性 | 本地保留FastDDS的实时性(5-10ms),远端用MQTT降低部署复杂度,兼顾实时性和易用性; |
2. 潜在劣势与解决方案
| 劣势 | 解决方案 |
|---|---|
| 中转站单点风险 | 1. 中转站进程加入心跳检测(本地EXE监控,异常则自动重启); 2. 关键主机可部署双中转站,MQTT Broker做主备切换; |
| 数据转换成本 | 封装通用转换模块:FastDDS IDL生成的类 ↔ ProtoBuf/JSON,一次性封装后所有主机复用; |
| MQTT延迟较高(100-200ms) | 1. MQTT Broker就近部署(如与主机同区域); 2. 配置MQTT QoS=0(实时性优先); 3. 高频数据压缩后传输; |
| 配置项较多 | 统一配置文件管理:将Domain ID、host_id、MQTT Broker地址等写入config.ini,所有模块读取配置,无需修改代码; |
四、Qt+C++落地实现要点(核心代码框架)
1. 中转站核心代码(FastDDS接收+MQTT转发)
#include<QCoreApplication>#include<QSettings>#include<QMqttClient>#include"fastdds/dds/domain/DomainParticipantFactory.hpp"#include"UnifiedDataPubSubTypes.h"// FastDDS IDL生成的类// 全局配置(从config.ini读取)QSettingssettings("config.ini",QSettings::IniFormat);intdomainId=settings.value("fastdds/domain_id").toInt();QString hostId=settings.value("mqtt/host_id").toString();QString mqttBroker=settings.value("mqtt/broker").toString();intmqttPort=settings.value("mqtt/port").toInt();// FastDDS数据监听类classFastDDSListener:publicDataReaderListener{public:voidon_data_available(DataReader*reader)override{UnifiedData data;SampleInfo info;if(reader->take_next_sample(&data,&info)==RETCODE_OK&&info.valid_data){// 1. FastDDS数据转换为ProtoBuf(或JSON)std::string serializedData;data.SerializeToString(&serializedData);// 2. 拼接MQTT主题(/host/device001/sensor/UnifiedData)QString mqttTopic=QString("/host/%1/sensor/%2").arg(hostId).arg(data.topic_name());// 3. MQTT发布QMqttClient*client=qobject_cast<QMqttClient*>(parent());client->publish(mqttTopic,QByteArray(serializedData.c_str(),serializedData.size()));}}};intmain(intargc,char*argv[]){QCoreApplicationa(argc,argv);// ========== 1. 初始化FastDDS(本机Domain ID) ==========DomainParticipant*participant=DomainParticipantFactory::get_instance()->create_participant(domainId,PARTICIPANT_QOS_DEFAULT);UnifiedDataPubSubType type;participant->register_type(&type);Topic*topic=participant->create_topic("UnifiedData",type.get_type_name(),TOPIC_QOS_DEFAULT);Subscriber*subscriber=participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);FastDDSListener listener;DataReader*reader=subscriber->create_datareader(topic,DATAREADER_QOS_DEFAULT,&listener);// ========== 2. 初始化MQTT客户端 ==========QMqttClient mqttClient;mqttClient.setHostname(mqttBroker);mqttClient.setPort(mqttPort);mqttClient.setClientId(hostId);// MQTT客户端ID=主机标识,便于Broker ACL管控mqttClient.connectToHost();// 绑定FastDDS监听器的父对象为MQTT客户端,便于转发listener.setParent(&mqttClient);// ========== 3. MQTT接收远端数据,转发到本地FastDDS ==========connect(&mqttClient,&QMqttClient::messageReceived,[&](constQByteArray&msg,constQMqttTopicName&topic){// 仅处理本机主题(避免跨主机数据)if(!topic.name().startsWith(QString("/host/%1/").arg(hostId)))return;// MQTT数据转换为FastDDS格式,发布到本机域UnifiedData data;data.ParseFromArray(msg.data(),msg.size());DataWriter*writer=participant->create_datawriter(topic,DATAWRITER_QOS_DEFAULT);writer->write(&data);});// 订阅本机MQTT主题mqttClient.subscribe(QMqttTopicFilter(QString("/host/%1/#").arg(hostId)));returna.exec();}2. 本地EXE代码(仅需FastDDS,无需关心MQTT)
#include<QCoreApplication>#include<QSettings>#include"fastdds/dds/domain/DomainParticipantFactory.hpp"#include"UnifiedDataPubSubTypes.h"intmain(intargc,char*argv[]){QCoreApplicationa(argc,argv);// 读取本机Domain ID(与中转站一致)QSettingssettings("config.ini",QSettings::IniFormat);intdomainId=settings.value("fastdds/domain_id").toInt();// FastDDS初始化(仅需3步,自动发现中转站)DomainParticipant*participant=DomainParticipantFactory::get_instance()->create_participant(domainId,PARTICIPANT_QOS_DEFAULT);UnifiedDataPubSubType type;participant->register_type(&type);Topic*topic=participant->create_topic("UnifiedData",type.get_type_name(),TOPIC_QOS_DEFAULT);// 发布数据(自动发现本机域内的订阅者,无需指定地址)Publisher*publisher=participant->create_publisher(PUBLISHER_QOS_DEFAULT);DataWriter*writer=publisher->create_datawriter(topic,DATAWRITER_QOS_DEFAULT);UnifiedData data;data.set_topic_name("UnifiedData");data.set_content("本地EXE的北斗数据");writer->write(&data);returna.exec();}3. 配置文件(config.ini,跨主机仅需修改此文件)
[fastdds] domain_id = 100 # 主机A=100,主机B=101,以此类推 [mqtt] host_id = device001 # 主机唯一标识 broker = 47.96.38.26 # MQTT Broker公网IP port = 1883五、最终建议
1. 架构选型结论
该架构(本地FastDDS+远端MQTT+双层隔离)是你场景的最优解:
- 满足“本地EXE仅订阅即可通信”:复用FastDDS自动配置/发现的优势,降低本地EXE开发成本;
- 满足“多主机数据隔离”:Domain ID物理隔离+MQTT主题/ACL逻辑隔离,安全性可控;
- 跨平台适配:FastDDS和Qt MQTT均支持Win/Linux/macOS,配置文件统一管理,部署灵活;
- 成本平衡:本地实时性(FastDDS)+ 远端易用性(MQTT),比纯FastDDS跨网段部署成本低,比纯MQTT本地通信实时性高。
2. 落地优先级
- 先完成单主机验证:部署中转站+本地EXE,测试FastDDS本地通信+MQTT转发;
- 配置Broker ACL规则,验证多主机数据隔离;
- 封装通用转换模块(FastDDS↔ProtoBuf),所有主机复用;
- 增加中转站容灾、数据压缩、心跳检测等优化。
3. 替代方案对比(仅作参考)
| 方案 | 隔离性 | 本地体验 | 远端部署成本 | 实时性 | 适配性 |
|---|---|---|---|---|---|
| 本地FastDDS+远端MQTT | 高 | 优 | 低 | 中高 | 优 |
| 纯FastDDS(跨网段) | 高 | 优 | 高(需DS集群) | 高 | 中 |
| 纯MQTT(本地+远端) | 中 | 差(手动配置) | 低 | 中 | 中 |
综上,该架构完美适配你的核心需求:本地FastDDS简化配置、远端MQTT降低部署成本、双层隔离保障多主机数据安全,且完全兼容Qt+C++跨平台开发体系。