You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

RTI Connext DDS跨域场景下订阅端无法写入AlertTopic主题的问题求助

RTI Connext DDS跨域场景下订阅端无法写入AlertTopic主题的问题求助

大家好,我最近在做一个RTI Connext DDS的小项目,遇到了跨域通信的问题,折腾好一阵没解决,来请教下各位大佬。

先说说我的场景:

  • 当发布端和订阅端在同一个域时,整个流程完全正常:发布端往SensorTopic推随机数,订阅端读取后再写入AlertTopic,一切都能正常工作。
  • 但把发布端放在域0、订阅端放在域1,通过路由服务转发SensorTopic的数据后,问题出现了:订阅端确实能成功收到SensorTopic的数据(我已经确认处理数据的回调函数被正常调用了),但订阅端往AlertTopic写的数据,用rtiddsspy完全监听不到,就像没写进去一样。

接下来是我的代码和配置:

发布端代码

#include <iostream>
#include <thread>
#include <random>
#include <rti/rti.hpp>
#include "sensor_data.hpp"

void publishSensor(const std::string& sensorName) {
    dds::domain::DomainParticipant participant(0);
    dds::topic::Topic<SensorData> sensorTopic(participant, "SensorTopic");
    dds::pub::DataWriter<SensorData> writer(sensorTopic);

    std::default_random_engine generator;
    std::normal_distribution<float> distribution(0.0, 1.0);
    SensorData sensorData { sensorName, 0 };

    while (true) {
        sensorData.value(distribution(generator));
        writer.write(sensorData);
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

int main(int argc, char *argv[]) {
    std::string sensor_name = (argc > 1) ? argv[1] : "Sensor1";
    publishSensor(sensor_name);
    return 0;
}

订阅端代码

#include <iostream>
#include <thread>
#include <rti/rti.hpp>
#include <dds/pub/ddspub.hpp>
#include <rti/sub/SampleProcessor.hpp>
#include "sensor_data.hpp"

using KeyedString = dds::core::KeyedStringTopicType;

int main(int argc, char *argv[]) {
    // 注意:这里用的是域1,为了接收域0的数据,我已经启动了路由服务
    dds::domain::DomainParticipant participant(1);

    // 读取来自SensorTopic的原始传感器数据
    dds::topic::Topic<SensorData> sensorTopic(participant, "SensorTopic");
    dds::sub::DataReader<SensorData> sensorReader(sensorTopic);

    // 创建用于写入分析后告警数据的主题
    dds::topic::Topic<KeyedString> alertTopic(participant, "AlertTopic");
    dds::pub::DataWriter<KeyedString> alertWriter(alertTopic);

    // 定义SampleProcessor,在回调里处理数据并写入AlertTopic
    rti::sub::SampleProcessor statusProcessor;
    statusProcessor.attach_reader(
        sensorReader,
        [alertWriter](const rti::sub::LoanedSample<SensorData>& sample) mutable {
            if (sample.info().valid()) {
                std::string alertMsg = "Processed sample: " + std::to_string(sample.data().value() * 0.1);
                KeyedString alert(sample.data().sensorName(), alertMsg);
                alertWriter.write(alert, sample.info().source_timestamp());
            }
        }
    );

    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(4));
    }
}

路由服务配置(alert_routing_service.xml)

<?xml version="1.0"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../resource/schema/rti_routing_service.xsd">
    <routing_service name="AlertRoutingService">
        <annotation>
            <documentation>
                <![CDATA[ Routes sensor data from domain 0 to domain 1. ]]>
            </documentation>
        </annotation>
        <domain_route name="Domain_0_to_1">
            <participant name="domain0">
                <domain_id>0</domain_id>
            </participant>
            <participant name="domain1">
                <domain_id>1</domain_id>
            </participant>
            <session name="Session">
                <topic_route name="RouteSensorData">
                    <input participant="domain0">
                        <topic_name>SensorTopic</topic_name>
                        <registered_type_name>SensorData</registered_type_name>
                    </input>
                    <output participant="domain1">
                        <topic_name>SensorTopic</topic_name>
                        <registered_type_name>SensorData</registered_type_name>
                    </output>
                </topic_route>
            </session>
        </domain_route>
    </routing_service>
</dds>

我用到的运行命令

  1. 监听AlertTopic的rtiddsspy命令:
../rti_connext_dds-7.5.0/bin/rtiddsspy -printSample COMPACT -topic AlertTopic
  1. 启动路由服务的命令:
~/rti_connext_dds-7.5.0/bin/rtiroutingservice -cfgFile alert_routing_service.xml -cfgName AlertRoutingService

我已经确认的点:

  • 路由服务正常工作,订阅端能收到域0的SensorTopic数据,回调函数确实被触发,能正确拿到SensorData的内容
  • 但调用alertWriter.write()后,rtiddsspy完全看不到AlertTopic的任何数据

有没有大佬能帮我看看,问题出在哪里?怎么才能让跨域的订阅端正常往AlertTopic写数据呢?


内容来源于stack exchange

火山引擎 最新活动