Skip to content

在 DDS(Data Distribution Service)里,Domain Participant 可以理解为“某个进程(或应用实例)加入到一个 DDS 通信域(Domain)后的代表对象”,它是 DDS 实体体系的根节点/入口,负责把应用纳入 DDS 的发现与通信机制中。

下面从“它是什么、解决什么问题、包含什么能力、与其他实体关系、工程上怎么用”几个角度理解。

1) Domain 与 DomainParticipant:先分清“域”和“参与者”

  • Domain(域):一个逻辑隔离的通信空间,用 domain_id 标识。不同 domain 之间默认互不发现、互不通信(类似“不同的广播域/不同的虚拟网络”)。
  • DomainParticipant(域参与者):应用在某个 domain_id 中的“身份/节点”。只要创建了 participant,就相当于这个进程(或进程内某个模块)加入了该域,开始参与:
    • 发现(Discovery)
    • 匹配(根据 Topic + QoS)
    • 数据收发(通过其下属的 Publisher/Subscriber/DataWriter/DataReader)

一句话:Domain 是房间号,DomainParticipant 是进入房间的“人”。

2) DomainParticipant 解决的核心问题

(a) “我是谁、我在哪个域里”

Participant 绑定到一个 domain_id,并携带一些本地信息(实现相关),让其他参与者能发现你、与你匹配。

(b) 发现与资源管理的边界

DDS 的自动发现通常是以 participant 为粒度进行的:

  • Participant 负责对外“宣告”自己、监听其他 participant
  • 并管理其内部创建的所有 DDS 实体(Topic、Publisher、Subscriber、DataWriter、DataReader)

你可以把它看成 DDS 的运行时上下文(runtime context)

3) DomainParticipant 之下有哪些实体(层级关系)

典型层级是:

  • DomainParticipant
    • Topic(主题:类型 + 名称)
    • Publisher
      • DataWriter(写某个 Topic)
    • Subscriber
      • DataReader(读某个 Topic)

也就是说:Writer/Reader 不能脱离 Participant 独立存在。Participant 像“工厂 + 容器”,创建并托管这些对象。

4) Participant 与“能不能通信”的关系

两个应用想通过 DDS 通信,通常需要满足(简化说):

  1. 同一个 domain_id
  2. Topic 名称与类型兼容
  3. QoS 可兼容(例如可靠性、历史深度、deadline 等匹配规则)
  4. 网络可达 + 安全策略允许(若启用 DDS Security)

其中第 1 条就是 Participant 层面的:participant 不在同一 domain,连发现都发生不了,更别提收发数据。

5) 一个进程要几个 Participant?

工程上常见两种策略:

一个进程一个 Participant(最常见)

优点:

  • 资源开销小(发现、内置端点、线程、socket 等通常按 participant 计)
  • 管理简单

一个进程多个 Participant(用于隔离/多域/多配置)

适用场景:

  • 同一进程要同时加入多个 domain(不同 domain_id
  • 需要在同一进程内做强隔离(不同的 QoS、不同安全身份、不同发现配置等,取决于实现) 代价:
  • 开销更高、配置更复杂(发现流量、端口/线程、内存等可能翻倍)

经验法则:除非有明确隔离需求,否则一个 participant 足够

6) 它和“节点/进程/容器”的关系(避免误解)

  • Participant 不是 Topic、也不是 Publisher/Subscriber 的同义词
  • Participant 通常对应“进程里的一个 DDS 栈实例”
  • 一个“应用进程”可以有多个 participant;一个 participant 下也可以有多个 publisher/subscriber、多个 writer/reader

因此它更像“DDS 通信栈的实例入口”,而不是业务概念本身。

基于 VitePress 构建