【FastDDS】Layer DDS之Domain ( 05-Creating a DomainParticipant)
Fast DDS 域参与者(DomainParticipant)的创建与删除详解
一、域参与者(DomainParticipant)的基础创建方式
域参与者(DomainParticipant
)的创建需通过域参与者工厂(DomainParticipantFactory
)单例的 create_participant()
成员函数完成——DomainParticipantFactory
本质上就是 DomainParticipant
的创建工厂。当域参与者的生命周期结束时,必须通过 delete_participant()
函数将其删除,具体删除细节可参考“域参与者的删除”章节。
(一)创建所需的参数说明
1. 必选参数
DomainId
(域ID):用于指定创建DomainParticipant
所属的域,是域的唯一标识。DomainParticipantQos
(域参与者服务质量):用于描述DomainParticipant
的行为特性。若传入的值为PARTICIPANT_QOS_DEFAULT
,则表示使用默认的DomainParticipantQos
配置。
除上述两个必选参数外,还可选择传入 DomainParticipantExtendedQos
(扩展域参与者服务质量)——该参数同时包含 DomainId
和 DomainParticipantQos
,可替代前两个必选参数使用。
2. 可选参数
- 监听器(Listener):需继承自
DomainParticipantListener
,用于实现响应DomainParticipant
事件与状态变化的回调函数。默认情况下,使用空回调函数(即不触发任何自定义逻辑)。 StatusMask
(状态掩码):用于激活或禁用DomainParticipantListener
中单个回调函数的触发。
(二)重要警告
根据 DDSI-RTPS V2.2 标准(第 9.6.1.1 节),默认端口会根据 DomainId
计算(具体计算规则详见“知名端口(Well Known Ports)”章节)。因此,建议使用小于 200 的 DomainId
——若 DomainId
超过 233,默认端口分配会持续失败。
(三)创建结果的判断
若创建过程中出现错误(例如传入的 QoS 不兼容或不受支持),create_participant()
会返回空指针(nullptr
)。因此,建议在创建后检查返回值是否为有效指针,以确保创建成功。
(四)基础创建方式的示例代码
以下代码展示了三种常见的基础创建场景:使用默认 QoS 且无监听器、使用自定义 QoS、使用默认 QoS 且带自定义监听器。
// 1. 使用默认DomainParticipantQos且无监听器创建DomainParticipant
// PARTICIPANT_QOS_DEFAULT 表示使用默认QoS
DomainParticipant* participant_with_default_attributes =DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_default_attributes)
{// 错误处理return;
}// 2. 传入自定义DomainParticipantQos创建DomainParticipant
DomainParticipantQos custom_qos;// (根据需求)修改QoS属性
// (...)DomainParticipant* participant_with_custom_qos =DomainParticipantFactory::get_instance()->create_participant(0, custom_qos);
if (nullptr == participant_with_custom_qos)
{// 错误处理return;
}// 3. 使用默认QoS且带自定义监听器创建DomainParticipant
// CustomDomainParticipantListener 是继承自 DomainParticipantListener 的自定义监听器
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_default_qos_and_custom_listener =DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT,&custom_listener);
if (nullptr == participant_with_default_qos_and_custom_listener)
{// 错误处理return;
}
二、基于配置文件创建域参与者(Profile-Based Creation)
除直接传入 DomainParticipantQos
外,还可通过配置文件(Profile)的名称创建 DomainParticipant
,具体需调用 DomainParticipantFactory
单例的 create_participant_with_profile()
成员函数。
(一)创建所需的参数说明
1. 必选参数
DomainId
(域ID):指定DomainParticipant
所属的域,需注意不要使用大于 200 的DomainId
(原因详见“域参与者的基础创建方式”中的警告)。- 配置文件名称:需为
DomainParticipant
应用的配置文件名称(配置文件需预先加载,详见下文说明)。
2. 可选参数
- 监听器(Listener):继承自
DomainParticipantListener
,用于实现事件与状态变化的回调函数,默认使用空回调。 StatusMask
(状态掩码):控制DomainParticipantListener
中单个回调的触发,默认启用所有事件的回调。
(二)前置条件:加载 XML 配置文件
使用配置文件创建前,必须预先加载包含该配置文件的 XML 文件(加载方式详见“从 XML 文件加载配置文件”章节)。若未加载,将无法找到指定配置文件,导致创建失败。
(三)基于配置文件创建的示例代码
// 第一步:加载包含配置文件的XML文件
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");// 1. 使用配置文件且无监听器创建DomainParticipant
DomainParticipant* participant_with_profile =DomainParticipantFactory::get_instance()->create_participant_with_profile(0, "participant_profile");
if (nullptr == participant_with_profile)
{// 错误处理return;
}// 2. 使用配置文件且带自定义监听器创建DomainParticipant
// CustomDomainParticipantListener 是继承自 DomainParticipantListener 的自定义监听器
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_profile_and_custom_listener =DomainParticipantFactory::get_instance()->create_participant_with_profile(0, "participant_profile",&custom_listener);
if (nullptr == participant_with_profile_and_custom_listener)
{// 错误处理return;
}
(四)创建结果的判断
与 create_participant()
类似,若创建过程出错(如 QoS 不兼容),create_participant_with_profile()
会返回空指针,建议创建后检查返回值的有效性。
三、基于默认配置文件创建域参与者
若环境中已导出某个配置文件(相关说明详见“XML 配置文件(XML profiles)”章节),可通过 DomainParticipantFactory
单例的 create_participant_with_default_profile()
成员函数创建 DomainParticipant
,此时会自动使用环境中导出的配置文件进行配置。
若环境中未导出配置文件,则会使用 DomainParticipantQos
的默认值创建 DomainParticipant
,且默认 DomainId
为 0。
(一)创建所需的参数说明
该方式仅包含可选参数,无必选参数:
- 监听器(Listener):继承自
DomainParticipantListener
,默认使用空回调。 StatusMask
(状态掩码):控制回调触发,默认启用所有事件。
(二)前置条件:加载 XML 配置文件
与“基于配置文件创建”相同,需预先加载 XML 配置文件(详见“XML 配置文件”章节),否则无法使用环境中导出的配置。
(三)基于默认配置文件创建的示例代码
// 1. 使用环境配置文件且无监听器创建DomainParticipant
DomainParticipant* participant =DomainParticipantFactory::get_instance()->create_participant_with_default_profile();
if (nullptr == participant)
{// 错误处理return;
}// 2. 使用环境配置文件且带自定义监听器创建DomainParticipant
// CustomDomainParticipantListener 是继承自 DomainParticipantListener 的自定义监听器
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_custom_listener =DomainParticipantFactory::get_instance()->create_participant_with_default_profile(&custom_listener, StatusMask::none()); // StatusMask::none() 表示禁用所有事件回调
if (nullptr == participant_with_custom_listener)
{// 错误处理return;
}
(四)创建结果的判断
create_participant_with_default_profile()
出错时会返回空指针,建议创建后检查返回值。
四、域参与者(DomainParticipant)的删除
DomainParticipant
必须通过 DomainParticipantFactory
单例的 delete_participant()
成员函数删除,且删除需满足严格的前置条件。
(一)删除的前置条件(重要)
只有当该 DomainParticipant
所属的所有实体(Entities)(包括发布者 Publisher、订阅者 Subscriber、主题 Topic)均已删除时,才能删除 DomainParticipant
。若存在未删除的实体,delete_participant()
会报错,且 DomainParticipant
不会被删除。
实体的删除有两种方式:
- 调用
DomainParticipant
的delete_contained_entities()
成员函数,批量删除其所属的所有实体。 - 手动调用
DomainParticipant
的对应删除函数,逐个删除实体(如delete_publisher()
删除发布者、delete_subscriber()
删除订阅者、delete_topic()
删除主题等)。
(二)删除域参与者的示例代码
// 第一步:创建DomainParticipant
DomainParticipant* participant =DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{// 错误处理return;
}// (根据需求)使用DomainParticipant进行通信
// (...)// 第二步:删除DomainParticipant所属的所有实体(批量删除)
if (participant->delete_contained_entities() != RETCODE_OK)
{// 域参与者删除其创建的实体失败,进行错误处理return;
}// 第三步:删除DomainParticipant
if (DomainParticipantFactory::get_instance()->delete_participant(participant) != RETCODE_OK)
{// 错误处理return;
}