本地FastDDS+远端MQTT转发(多主机数据隔离)架构设计与落地

文章目录

本地FastDDS+远端MQTT转发(多主机数据隔离)架构设计与落地

一、架构核心设计(贴合你的多主机/Qt+C++场景)

该架构的核心是**"单主机FastDDS域隔离 + 中转站统一转发 + MQTT主题/ACL远端隔离"**,每台主机部署一个"FastDDS-MQTT中转站",作为本地FastDDS和远端MQTT的唯一桥梁,既保留FastDDS本地自动配置的优势,又通过MQTT实现跨主机/远端通信,同时保障多主机数据隔离。

1. 整体架构图(文字版)

text 复制代码
┌────────────────────────────────────────────── 主机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直接访问远端数据。

2. 远端层:MQTT主题+ACL 逻辑隔离

(1)MQTT主题命名规则(统一格式,强制隔离)

定义全局唯一的主题格式,将"主机标识"作为主题前缀,确保不同主机的数据不会混流:

复制代码
/host/{主机唯一标识}/{数据类型}/{FastDDS Topic名}
  • 示例:
    • 主机A(标识device001)的北斗数据:/host/device001/sensor/BeidouData;
    • 主机B(标识device002)的USBL数据:/host/device002/sensor/USBLData;
  • 中转站自动拼接规则:读取本机配置的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转发)

cpp 复制代码
#include <QCoreApplication>
#include <QSettings>
#include <QMqttClient>
#include "fastdds/dds/domain/DomainParticipantFactory.hpp"
#include "UnifiedDataPubSubTypes.h" // FastDDS IDL生成的类

// 全局配置(从config.ini读取)
QSettings settings("config.ini", QSettings::IniFormat);
int domainId = settings.value("fastdds/domain_id").toInt();
QString hostId = settings.value("mqtt/host_id").toString();
QString mqttBroker = settings.value("mqtt/broker").toString();
int mqttPort = settings.value("mqtt/port").toInt();

// FastDDS数据监听类
class FastDDSListener : public DataReaderListener {
public:
    void on_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()));
        }
    }
};

int main(int argc, char *argv[]) {
    QCoreApplication a(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, [&](const QByteArray& msg, const QMqttTopicName& 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)));

    return a.exec();
}

2. 本地EXE代码(仅需FastDDS,无需关心MQTT)

cpp 复制代码
#include <QCoreApplication>
#include <QSettings>
#include "fastdds/dds/domain/DomainParticipantFactory.hpp"
#include "UnifiedDataPubSubTypes.h"

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 读取本机Domain ID(与中转站一致)
    QSettings settings("config.ini", QSettings::IniFormat);
    int domainId = 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);

    return a.exec();
}

3. 配置文件(config.ini,跨主机仅需修改此文件)

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. 落地优先级

  1. 先完成单主机验证:部署中转站+本地EXE,测试FastDDS本地通信+MQTT转发;
  2. 配置Broker ACL规则,验证多主机数据隔离;
  3. 封装通用转换模块(FastDDS↔ProtoBuf),所有主机复用;
  4. 增加中转站容灾、数据压缩、心跳检测等优化。

3. 替代方案对比(仅作参考)

方案 隔离性 本地体验 远端部署成本 实时性 适配性
本地FastDDS+远端MQTT 高 优 低 中高 优
纯FastDDS(跨网段) 高 优 高(需DS集群) 高 中
纯MQTT(本地+远端) 中 差(手动配置) 低 中 中

综上,该架构完美适配你的核心需求:本地FastDDS简化配置、远端MQTT降低部署成本、双层隔离保障多主机数据安全,且完全兼容Qt+C++跨平台开发体系。

相关推荐
HackTwoHub1 小时前
REA逆向一切!渗透逆向新利器、MCP 驱动全栈逆向方案,解析原生二进制、EXE、APK,高效挖掘程序底层漏洞
网络·安全·web安全·网络安全·系统安全
小趴菜一只1 小时前
SIEM-wazuh安装过程
运维·windows·安全·网络安全
SKH.1 小时前
Linux驱动-key、中断
linux·运维·服务器
励志师code1 小时前
数据搬运与存储对接实战:rclone / juicesync 迁移 + 目录对账 + 容器多源挂载
运维·云计算
星恒随风1 小时前
Linux进程间通信(一):从匿名管道、命名管道到进程池,深入理解Pipe、FIFO与文件描述符
linux·运维·笔记·学习·状态模式
pt10432 小时前
Cisco设备网络安全系列-3:远程访问虚拟专用网、站点间虚拟专用网与Cisco SD-WAN安全
网络·安全
刘胡子大叔2 小时前
服务器不能编译怎么办
运维·服务器
每日品牌解读2 小时前
企业经由 API 调用大模型,推荐哪些拥有数据隐私保护能力的平台?
运维·网络
竣达技术3 小时前
就地显示 + 远程上传,铅酸蓄电池在线监测完整解决方案
运维·数据库