一些有关 FastDDS 的基本概念

之前分享过一次关于 FastDDS 的调研,简单来说就是其作为消息中间件,具有很强的实时性、可靠性、灵活性等优点,可以简化开发者对通信层面的关注,可以集中精力专注于业务的研究。这篇分享一下 FastDDS 的一些基本概念。

FastDDS 有两套 API,接近传输层的 RTPS API 和规范的 DDS API

1.1 传输层

包含了兼容各平台的 TCP / UDP / SHM 协议的实现

1.2 RTPS 层

使用 RTPS 层可以直接操作传输层提供的接口,类似直接对内存操作,更加灵活。

1
2
3
4
5
6
7
8
9
10
11
12
13
int index = 3;
string message = "hello world";

ch->serializedPayload.length = 200;
memcpy(ch->serializedPayload.data, &index, sizeof(index));
memcpy(ch->serializedPayload.data + sizeof(index), message.c_str(), 20);
mp_history->add_change(ch);

std::cout << "index = " << *(int*) ch->serializedPayload.data
<< "; message = " << ch->serializedPayload.data + sizeof(index)
<< std::endl;
-----
>> index = 3; message = hello

1.3 DDS 层

DDS 层与 RTPS 层最大的区别是使用 主题 (Topic) 的概念,在主题的基础上包含发布、订阅、消息过滤等功能。

主题使用接口描述语言 (Interface Description Language, IDL),将传输的数据结构建模为类型化接口:

1
2
3
4
5
6
7
// HelloWorld.idl

struct HelloWorld
{
unsigned long index;
string message;
};

对类型直接操作:

1
2
3
4
5
HelloWorld hello;
hello.index(3);
hello.message("hello world");

writer->write(&hello);

1.4 Discovery

FastDDS 的”发现”机制,用于自动发现新上线的客户端。下图分别为分布式(Simple Discovery)、集中式(Discovery Service)发现机制。

image

a. Simple Discovery

RTPS 协议标准的发现机制,通过多播互相发现。

b. Discovery Server

使用 Discovery Server 可以减少流量,且不需要多播功能。

c. Others

无法使用多播,如 Wi-Fi;或已知拓扑结构,想减少流量。

  • Peer-to-Peer Discovery : 配置 peer list,使用单播(metatraffic unicast)
  • Static Discovery : 手动配置 user locators,不使用 metatraffic

1.5 Listening Locators

Locator_t 代表传输信道,包含 IP 端口 等信息。

Locators 分为两类,Metatraffic locators User locators 。其中,前者主要用于 Discovery,后者用于传输用户的数据。当用户不手动配置 Locators 时,其端口按特定的规则分配:

Traffic type Well-known port expression pid = 1 pId = 2 pId = 3
Metatraffic multicast 7400 + 250 * domainId 7400 7400 7400
Metatraffic unicast 7400 + 250 * domainId + 10 + 2 * participantId 7412 7414 7416
User multicast 7400 + 250 * domainId + 1 7401 7401 7401
User unicast 7400 + 250 * domainId + 11 + 2 * participantId 7413 7415 7417