Fast DDS 域参与者(DomainParticipant)模块详解
一、域参与者(DomainParticipant)基础概述
域参与者(DomainParticipant)是应用程序接入某一域(Domain)的入口。每个域参与者从创建之初就与单个域绑定,且包含该域相关的所有实体(Entities)。同时,它还充当着发布者(Publisher)、订阅者(Subscriber)和主题(Topic)的创建工厂。
域参与者的行为可通过DomainParticipantQos(域参与者服务质量)中指定的QoS值进行修改。这些QoS值既可以在创建域参与者时设置,也可在后续通过DomainParticipant::set_qos()成员函数进行调整。
作为一种实体(Entity),域参与者可关联一个DomainParticipantListener(域参与者监听器)。当域参与者实例的状态发生变化时,该监听器会收到通知。
二、域参与者服务质量(DomainParticipantQos)
DomainParticipantQos用于控制域参与者的行为,其内部包含以下QosPolicy(服务质量策略)对象,各策略的访问器/修改器及可变性信息如下表所示:
| QosPolicy(服务质量策略)类 | 访问器/修改器(Accessor/Mutator) | 可变性(Mutable) |
|---|---|---|
| UserDataQosPolicy(用户数据服务质量策略) | user_data() | 是(Yes) |
| EntityFactoryQosPolicy(实体工厂服务质量策略) | entity_factory() | 是(Yes) |
| ParticipantResourceLimitsQos(参与者资源限制服务质量) | allocation() | 否(No) |
| PropertyPolicyQos(属性服务质量策略) | properties() | 否(No) |
| WireProtocolConfigQos(有线协议配置服务质量) | wire_protocol() | 否(No)* |
| TransportConfigQos(传输配置服务质量) | transport() 和 setup_transports() | 否(No) |
| FlowControllersQos(流控制器服务质量) | flow_controllers() | 否(No) |
| ThreadSettings(线程设置) | builtin_controllers_sender_thread() | 否(No) |
| ThreadSettings(线程设置) | timed_events_thread() | 否(No) |
| ThreadSettings(线程设置) | discovery_server_thread() | 否(No) |
| ThreadSettings(线程设置) | typelookup_service_thread() | 否(No) |
| ThreadSettings(线程设置) | security_log_thread() | 否(No) |
(一)重要说明
- WireProtocolConfigQos的特殊可变性:WireProtocolConfigQos中唯一可修改的字段是
m_DiscoveryServers,该字段包含在builtin(内置)下的discovery_config(发现配置)中(详见“运行时修改远程服务器列表”章节)。 - 统计支持对QoS的影响:调用
create_participant()(创建参与者)函数时,若Fast DDS编译时启用了统计支持(默认启用,详见“CMake选项”),则内部的DomainParticipantQos可能与输入的DomainParticipantQos不一致(详见“统计模块设置”章节)。这意味着,若应用程序希望在创建域参与者后进一步修改DomainParticipantQos,需按以下步骤操作:- 通过
DomainParticipant::get_qos()获取内部的DomainParticipantQos。 - 对获取的QoS进行所需修改。
- 通过
DomainParticipant::set_qos()更新DomainParticipantQos。
- 通过
(二)域参与者QoS的修改规则
对于已创建的域参与者,可通过DomainParticipant::set_qos()成员函数修改其QoS值。但若尝试修改已启用域参与者的不可变QoS策略,将会触发错误——此时不会应用任何修改,域参与者仍保持原有的DomainParticipantQos配置。
(三)域参与者QoS操作示例代码
// 使用默认DomainParticipantQos创建域参与者
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
// 错误处理
return;
}
// 获取当前QoS或重新创建一个新的QoS对象
DomainParticipantQos qos = participant->get_qos();
// 修改QoS属性
qos.entity_factory().autoenable_created_entities = false;
// 为域参与者分配新的QoS配置
participant->set_qos(qos);
三、默认域参与者服务质量(Default DomainParticipantQos)
默认域参与者服务质量(Default DomainParticipantQos)指的是通过域参与者工厂(DomainParticipantFactory)单例的get_default_participant_qos()成员函数返回的QoS值。特殊值PARTICIPANT_QOS_DEFAULT可作为QoS参数,用于create_participant()或DomainParticipant::set_qos()成员函数,标识使用当前的默认DomainParticipantQos。
(一)默认QoS的初始状态与修改规则
- 初始状态:系统启动时,默认DomainParticipantQos等同于默认构造值
DomainParticipantQos()。 - 修改方式:可通过域参与者工厂单例的
set_default_participant_qos()成员函数随时修改默认DomainParticipantQos。需注意,修改默认QoS不会影响已创建的域参与者实例。
(二)默认QoS操作示例代码
// 获取当前默认QoS或重新创建一个新的QoS对象
DomainParticipantQos qos_type1 = DomainParticipantFactory::get_instance()->get_default_participant_qos();
// 修改QoS属性(此处省略具体修改逻辑)
// (...)
// 将修改后的QoS设置为新的默认TopicQos
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(qos_type1) !=
RETCODE_OK)
{
// 错误处理
return;
}
// 使用新的默认DomainParticipantQos创建域参与者
DomainParticipant* participant_with_qos_type1 =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_qos_type1)
{
// 错误处理
return;
}
// 重新创建一个新的QoS对象(qos_type2)
DomainParticipantQos qos_type2;
// 修改QoS属性(此处省略具体修改逻辑)
// (...)
// 将qos_type2设置为新的默认TopicQos
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(qos_type2) !=
RETCODE_OK)
{
// 错误处理
return;
}
// 使用新的默认TopicQos创建域参与者
DomainParticipant* participant_with_qos_type2 =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_qos_type2)
{
// 错误处理
return;
}
// 将默认DomainParticipantQos重置为原始默认构造值
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(PARTICIPANT_QOS_DEFAULT)
!= RETCODE_OK)
{
// 错误处理
return;
}
// 上述重置操作等同于以下代码
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(DomainParticipantQos())
!= RETCODE_OK)
{
// 错误处理
return;
}
(三)PARTICIPANT_QOS_DEFAULT的特殊含义
set_default_participant_qos()成员函数也接受PARTICIPANT_QOS_DEFAULT作为输入参数,此时会将当前默认DomainParticipantQos重置为默认构造值DomainParticipantQos()。以下是相关操作示例:
// 创建自定义的DomainParticipantQos
DomainParticipantQos custom_qos;
// 修改QoS属性(此处省略具体修改逻辑)
// (...)
// 使用自定义DomainParticipantQos创建域参与者
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, custom_qos);
if (nullptr == participant)
{
// 错误处理
return;
}
// 将域参与者的QoS设置为默认值
if (participant->set_qos(PARTICIPANT_QOS_DEFAULT) != RETCODE_OK)
{
// 错误处理
return;
}
// 上述设置默认QoS的操作等同于以下代码
if (participant->set_qos(DomainParticipantFactory::get_instance()->get_default_participant_qos())
!= RETCODE_OK)
{
// 错误处理
return;
}
(四)PARTICIPANT_QOS_DEFAULT的含义差异
需注意,PARTICIPANT_QOS_DEFAULT在不同场景下含义不同:
- 在
create_participant()和DomainParticipant::set_qos()中,它指代get_default_participant_qos()返回的默认DomainParticipantQos。 - 在
set_default_participant_qos()中,它指代默认构造的DomainParticipantQos()。
四、扩展域参与者服务质量(DomainParticipantExtendedQos)
DomainParticipantExtendedQos是DomainParticipantQos的扩展类,它同时包含域参与者的DomainId(域ID)和DomainParticipantQos对象。该类的作用是简化域参与者的创建与配置——只需在单个对象中指定所有必要设置,即可完成域参与者的相关配置。
(一)扩展QoS的获取与使用
- 从配置文件获取扩展QoS:可通过
get_participant_extended_qos_from_profile()从已加载的配置文件中获取DomainParticipantExtendedQos,再使用该扩展QoS创建域参与者。对于已创建的域参与者,其QoS的修改方式与通过DomainParticipantQos创建时的修改方式类似。 - 示例代码:
// 从配置文件获取DomainParticipantExtendedQos
DomainParticipantExtendedQos profile_extended_qos;
DomainParticipantFactory::get_instance()->get_participant_extended_qos_from_profile("participant_profile",
profile_extended_qos);
// 使用扩展QoS创建域参与者
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(profile_extended_qos);
if (nullptr == participant)
{
// 错误处理
return;
}
(二)从原始XML字符串获取扩展QoS
除了从配置文件获取,也可直接从原始XML字符串中填充DomainParticipantExtendedQos对象,无需预先加载任何配置文件。关于具体实现方式,可参考“从原始XML配置文件获取QoS”章节。

112

被折叠的 条评论
为什么被折叠?



