Mental Model
┌─────────────────────────────────────┐
│ YOUR APPLICATION │
│ publisher.publish(sensor_data) │
│ subscriber.on_data(callback) │
├─────────────────────────────────────┤
│ DDS LAYER │
│ - Topic naming & type system │
│ - QoS enforcement │
│ - History / durability cache │
│ - Liveliness monitoring │
│ - Content filtering │
├─────────────────────────────────────┤
│ RTPS LAYER │
│ - Wire encoding of messages │
│ - HEARTBEAT / ACKNACK reliability │
│ - SPDP / SEDP discovery │
│ - Sequence numbers │
│ - Vendor extensions (Unknown[80]) │
├─────────────────────────────────────┤
│ UDP / TCP │
└─────────────────────────────────────┘
Example setup - RTPS over TCP for discovery, data over UDP
flowchart TD
subgraph AppLayer["Application Layer"]
PUB["Publisher\npublish(sensor_data)\nTopic: /sensor\nQoS: reliable"]
SUB_L["Subscriber (local)\non_data(callback)\nTopic: /sensor"]
SUB_R["Subscriber (remote)\non_data(callback)\nTopic: /sensor"]
end
subgraph Discovery["Discovery Phase (TCP + UDP)"]
D1["TCP handshake → .176:7499"]
D2["UDP: DATA(p) → loopback + .157\n(SPDP: announce participant)"]
D3["TCP: 642B → discovery server\n(forward DATA(p))"]
D4["TCP: 138B ← server\n(ACK)"]
D5["TCP: 690B ← server\n(peer registry: endpoints + QoS)"]
D6["SEDP match: topic + type + QoS\n(inside TCP tunnel)"]
end
subgraph Reliability["Reliability Init (UDP)"]
R1["UDP: HEARTBEAT x6 → loopback + .157\n(writer: here are my sequence numbers)"]
R2["UDP: ACKNACK x14 ← loopback + .157\n(readers: missing seqN, resend)\n2 bursts 11ms apart — NACK storm"]
R3["UDP: retransmit DATA(m)\n(storm resolved)"]
end
subgraph TopicExchange["Topic Data Exchange (UDP)"]
T1["UDP: DATA(m) → .157\n(remote subscriber receives sample)"]
T2["UDP: DATA(m) → loopback\n(local subscriber receives sample)"]
T3["UDP: DATA(m) + HEARTBEAT → loopback + .157\n(piggybacked: data + reliability check)"]
T4["UDP: ACKNACK ← loopback + .157\n(readers confirm — no missing samples)"]
end
subgraph Steady["Steady State every 100ms"]
S1["UDP: DATA(p) → loopback + .157\n(SPDP keepalive)"]
S2["TCP: 642B → discovery server"]
S3["TCP: 138B + 690B ← server"]
S4["UDP: DATA(p) → loopback only\n(2nd local participant)"]
end
PUB -->|"DDS match via SEDP"| SUB_L
PUB -->|"DDS match via SEDP"| SUB_R
PUB --> D1 --> D2 --> D3 --> D4 --> D5 --> D6
D6 --> R1 --> R2 --> R3
R3 --> T1
R3 --> T2
T1 & T2 --> T3
T3 -->|"readers ACK"| T4
T4 --> S1 --> S2 --> S3
S3 --> T3
S1 --> S4
Packet Level
── Discovery Phase ───────────────────────────────────────────────────────────────────────
[TCP] 192.168.2.13 → 172.28.16.176:7499 SYN / SYN-ACK / ACK (handshake)
[TCP] 192.168.2.13 → 172.28.16.176:7499 68B each way (session init)
[RTPS] 192.168.2.13 → loopback + .157 DATA(p) (SPDP: announce participant)
[TCP] 192.168.2.13 → 172.28.16.176:7499 642B (forward DATA(p) to server)
[TCP] 172.28.16.176 → 192.168.2.13 138B (server ACK)
[TCP] 172.28.16.176 → 192.168.2.13 690B (peer registry: endpoints + QoS)
[TCP] <inside tunnel> DATA(w) / DATA(r) (SEDP: topic + type + QoS match)
── Reliability Init ──────────────────────────────────────────────────────────────────────
[RTPS] 192.168.2.13 → loopback + .157 HEARTBEAT x6 (writer: here are my sequence numbers)
[RTPS] 192.168.2.13 → loopback + .157 ACKNACK x14 in 2 bursts (readers: missing seqN — NACK storm)
[RTPS] 192.168.2.13 → loopback + .157 DATA(m) retransmit (storm resolved)
── Topic Data Exchange ───────────────────────────────────────────────────────────────────
[RTPS] 192.168.2.13 → 172.28.16.157 DATA(m) (remote subscriber: sample delivered)
[RTPS] 192.168.2.13 → 192.168.2.13 DATA(m) (local subscriber: sample delivered)
[RTPS] 192.168.2.13 → loopback + .157 DATA(m) + HEARTBEAT (piggybacked: data + reliability check)
[RTPS] loopback + .157 → 192.168.2.13 ACKNACK (readers confirm — no missing samples)
── Steady State (every 100ms) ────────────────────────────────────────────────────────────
[RTPS] 192.168.2.13 → loopback + .157 DATA(p) (SPDP keepalive)
[TCP] 192.168.2.13 → 172.28.16.176:7499 642B (forward to server)
[TCP] 172.28.16.176 → 192.168.2.13 138B + 690B (server response)
[RTPS] 192.168.2.13 → loopback + .157 DATA(m) + HEARTBEAT (topic data + reliability)
[RTPS] loopback + .157 → 192.168.2.13 ACKNACK (readers confirm)
[RTPS] 192.168.2.13 → loopback only DATA(p) (2nd local participant)
References