Topic · Quickstart

Dev-Install — in 5 Minuten zum ersten Sample

Vom leeren Projekt zum ersten Pub/Sub-Roundtrip auf dem Loopback: ein neues Cargo-Projekt, drei Crates als Dependency, ~15 Zeilen Code, cargo run. Danach: Feature-Flag-Builds (warum drei?), Dev-Toolchain, Config-Knobs und Plattform-Support. Diese Page ist Rust-fokussiert — für C++, C#, Java, Python, TypeScript oder C-FFI siehe Sprach-Auswahl.

MSRV: Rust 1.88 · Edition 2024 Tier-1-Plattformen: Linux x86_64/aarch64 Lizenz: Apache 2.0

Welche Sprache?

ZeroDDS ist Pure-Rust unter der Haube, mit nativen Bindings für 7 weitere Sprachen. Jede hat ihren eigenen 5-Minuten-Quickstart — Install, Pub/Sub-Code, Run.

SpracheInstallVoraussetzungenEigenheitenQuickstart
Rust (Primärpfad)cargo add zerodds-dcpsRust 1.88+ · Edition 2024Pure-Rust · async/streams · no_std-tauglichunten ↓
C++-lzerodds + headersC++17 · libzerodds.soDDS-PSM-Cxx 1.0 · ABI-stabil · zerodds-idlc --cpp/bindings/cpp/ →
C# / .NETdotnet add package ZeroDDS.NET 8 + netstandard2.1NativeAOT · async/await · Source-Generators/bindings/csharp/ →
JavaMaven / GradleJDK 17+ (21+ für Virtual-Threads)Pure-Java · org.omg.dds.* · kein JNI/bindings/java/ →
Pythonpip install zeroddsCPython 3.8–3.14 (abi3-py38)@idl_struct · AsyncIO · QoS-Builder/bindings/python/ →
TypeScript (Node)npm install @zerodds/nodeNode 18 LTS+N-API · strict TS · async/streams/bindings/typescript-node/ →
TypeScript (Browser)npm install @zerodds/wasmChrome 89+ · Firefox 89+ · Safari 15+WASM · WebSocket-Bridge nötig/bindings/typescript-wasm/ →
C-FFI-lzerodds + zerodds.hC99+ oder C-InteropStable ABI · für Go, Zig, Ada, MATLAB, …/bindings/c-ffi/ →

Die Rust-Page (unten) ist gleichzeitig die Pure-Rust-Stack-Übersicht — Feature-Flags, Dev-Toolchain, Config, Plattform-Support. Wer in einer anderen Sprache anfängt, geht direkt zur Sprach-Page; die meisten Sections darunter (Config, Plattformen, Dev-Toolchain) gelten parallel.

5-Minuten-Quickstart (Rust)

Ein neues Cargo-Projekt, drei Dependencies, ein Publisher und ein Subscriber im selben Prozess. Läuft auf jedem System mit Rust 1.88+, ohne Setup.

1 · Cargo-Projekt + Dependencies

cargo new zerodds-hello --bin
cd zerodds-hello

Cargo.toml:

[package]
name = "zerodds-hello"
version = "0.1.0"
edition = "2024"

[dependencies]
zerodds-dcps = "1.0.0-rc.3"

Das ist alles. zerodds-dcps zieht alle benötigten Layer-Crates transitiv (foundation, cdr, qos, types, rtps, discovery, transport, transport-udp).

2 · Erste Pub/Sub-Schleife

src/main.rs:

use std::time::Duration;
use zerodds_dcps::*;

fn main() -> Result<()> {
    let factory = DomainParticipantFactory::instance();
    let participant = factory.create_participant(0, DomainParticipantQos::default())?;

    let topic = participant.create_topic::<RawBytes>("Chatter", TopicQos::default())?;
    let publisher = participant.create_publisher(PublisherQos::default());
    let subscriber = participant.create_subscriber(SubscriberQos::default());

    let writer = publisher.create_datawriter::<RawBytes>(&topic, DataWriterQos::default())?;
    let reader = subscriber.create_datareader::<RawBytes>(&topic, DataReaderQos::default())?;

    writer.wait_for_matched_subscription(1, Duration::from_secs(5))?;
    reader.wait_for_matched_publication(1, Duration::from_secs(5))?;

    writer.write(&RawBytes::new(b"hello".to_vec()))?;
    reader.wait_for_data(Duration::from_secs(3))?;

    for sample in reader.take()? {
        println!("got: {:?}", sample.data);
    }
    Ok(())
}

▶ Runnable example: rust-dev-install-hello

3 · Bauen + laufen

cargo run --release

Erwartete Ausgabe: got: [104, 101, 108, 108, 111] (das "hello" als bytes). Wenn das läuft, ist der Stack komplett funktional — Discovery + RTPS + UDP-Loopback + DCPS-API.

Cargo zieht erst die Welt: ZeroDDS hat ~90 Workspace-Crates, der erste cargo build kompiliert ein paar hundert MB an Abhängigkeiten. Plane 1-2 Min für den ersten Build ein, danach läuft inkrementell in <1 s.

Feature-Flags — warum drei Builds

ZeroDDS-Crates haben drei Build-Profile, die unterschiedliche Plattform-Anforderungen bedienen. Default-Feature ist std — der Normalfall für Server, Desktop, Container.

FeatureDefault?PlattformWas es bringtWann nutzen
stdLinux · macOS · Windows · *BSDVolle Standard-Library, Thread-Pool, OS-Sockets, Filesystem.Server, Desktop, Container — der Normalfall.
allocEmbedded mit Allocator (Tock-OS, RTOS mit alloc)Heap erlaubt (Vec, String), aber kein std (kein Threads, kein FS).MCU mit RTOS, der einen Allocator bereitstellt. Cortex-M7/A-Class.
safetyalle (orthogonal zu std/alloc)Extra Runtime-Checks: Panic-on-Drift bei internen Invarianten, strikte Bounds-Checks, Tagged-State-Machines.Compliance-Builds (CRA-Audit, ISO-26262-Vorbereitung), Pre-Production-Härtung.
(no default-features)Freestanding · Bare-Metal · #![no_std]Strikter no_std, kein Heap. Nur konst-evaluierbare Surfaces.Cortex-M0/M3-Class ohne Allocator, RTOS-Kernel-Bibliotheken.

Beispiele:

# Server-Build (Default)
zerodds-dcps = "1.0.0-rc.3"

# Embedded mit Allocator (alloc + safety)
zerodds-foundation = { version = "1.0.0-rc.3", default-features = false, features = ["alloc", "safety"] }
zerodds-cdr        = { version = "1.0.0-rc.3", default-features = false, features = ["alloc"] }

# Strict no_std (Bare-Metal)
zerodds-foundation = { version = "1.0.0-rc.3", default-features = false }
zerodds-cdr        = { version = "1.0.0-rc.3", default-features = false }

Wichtig: der volle DCPS-Stack (zerodds-dcps) braucht std (Threads für Discovery, OS-Sockets für UDP). Die Layer-1-Crates (foundation, cdr, qos, types) laufen no_std-fähig — für Embedded baut man typisch nur die Encoder/Decoder ein und nutzt eine externe Transport-Brücke.

Dev-Toolchain

Was du auf dem Dev-System brauchst.

Rust

# rustup falls noch nicht da
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# MSRV explizit setzen (Workspace-Wert)
rustup install 1.88
rustup default 1.88

# Komponenten
rustup component add clippy rustfmt rust-src

System-Pakete

ZeroDDS hat sehr wenige System-Dependencies; das meiste ist Pure-Rust.

PlattformPaketeWarum
Ubuntu/Debianbuild-essential pkg-config libssl-devLinker, OpenSSL für DDS-Security-Tests
Fedora/RHELgcc pkg-config openssl-develdito
macOSXcode-CLT (xcode-select --install)Linker, macOS-SDK
WindowsVisual Studio Build Tools (C++ Workload)MSVC-Linker

Optional — Cross-Vendor-Tests

# Linux: Cyclone DDS für Live-Interop-Tests
sudo apt install cyclonedds-tools     # liefert ddsperf, ddsls

# macOS via Homebrew
brew install cyclonedds

Damit laufen die crates/discovery/tests/cyclone_live_* Cross-Vendor-Tests; ohne werden sie geskipped.

Editor-Setup

  • VS Code: rust-analyzer-Extension. Im Workspace funktioniert es out-of-the-box (90+ Crates indexieren ~30 s beim ersten Open).
  • JetBrains: RustRover oder IntelliJ + Rust-Plugin.
  • Vim/Neovim: rust-analyzer via LSP-Client (coc.nvim, nvim-lspconfig).
  • Format-on-Save: rustfmt mit Workspace-Default (rustfmt.toml im Root).

Runtime-Config — was Devs wirklich anpassen

Install ist nicht nur Build — die meisten Probleme entstehen bei der Runtime-Konfiguration. Was sind die wichtigen Knobs?

Domain-ID

Alle Participants im gleichen Domain sprechen miteinander, alle anderen sind unsichtbar. Default 0 ist OK für Dev — produktiv pro Tenant/Stage eine eigene ID:

let participant = factory.create_participant(42, DomainParticipantQos::default())?;

Port-Mapping folgt DDSI-RTPS §9.6.1.4: port = 7400 + 250 * domain_id. Maximum-Domain-ID ist 232 (sonst >65535-Port).

Discovery-Multicast

SPDP nutzt per Default Multicast 239.255.0.1. Klappt auf LAN out-of-the-box. Probleme: Container-Netzwerke (Docker-Bridge blockt Multicast), Cross-Subnet (Router-Konfig nötig), Cloud-VPC (kein Multicast).

Wenn Multicast nicht geht: TCP-Backend + Static-Peers (siehe Transport-Tuning Rezept 2).

Fast-Discovery für Dev-Loops

Default-Discovery-Heartbeat ist 1 s. Für Dev-Loops (run, write, exit, run) zu langsam. Fast-Mode:

use zerodds_dcps::runtime::RuntimeConfig;

let cfg = RuntimeConfig {
    tick_period: Duration::from_millis(20),
    spdp_period: Duration::from_millis(100),
    ..RuntimeConfig::default()
};
let participant = factory.create_participant_with_config(0, DomainParticipantQos::default(), cfg)?;

▶ Runnable example: rust-dev-install-runtimeconfig

Damit ist Match-Latenz unter 200 ms. Nicht produktiv — 10× mehr Discovery-Traffic.

Logging

ZeroDDS nutzt tracing. Im Dev:

# Cargo.toml
tracing-subscriber = "0.3"

# main.rs
fn main() {
    tracing_subscriber::fmt().with_max_level(tracing::Level::DEBUG).init();
    // ... rest
}

# CLI
RUST_LOG=zerodds=debug cargo run

Strukturiertes Logging mit Span-Trees zeigt Discovery-Flow, Sample-Path, Retransmits.

QoS

Out of the box gelten die DDS-Spec-Defaults (§2.2.3.14, siehe QoS Reference): Writer=Reliable, Reader=BestEffort, History=KeepLast(1), Durability=Volatile. Weil der Reader per Default BestEffort anfordert, ist die effektive Zustellung best-effort — für garantierte Zustellung setzt du den Reader explizit auf Reliable. Für State-Topics zusätzlich Durability=TransientLocal, damit Late-Joiner den letzten Wert sehen. Fertige Profile: QoS Cookbook.

Aus dem Source bauen

Für Mitarbeit am Stack oder lokale Patches.

git clone https://github.com/zero-objects/zero-dds.git
cd zero-dds
cargo build --workspace --release
cargo test --workspace

Erwartung:

  • Erster Build: 5-10 Min auf einem 8-Core, je nach Disk.
  • Inkrementell: <1 s pro Crate.
  • Volle Test-Suite: ~3-5 Min (~5400 Tests).

Pre-Commit-Checks (Memory: vor jedem Push laufen lassen):

cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo run -p dds-lint -- check crates/

Crates als path-Dep für Patches:

# Cargo.toml im konsumierenden Projekt
[patch.crates-io]
zerodds-foundation = { path = "/home/you/zero-dds/crates/foundation" }
zerodds-dcps       = { path = "/home/you/zero-dds/crates/dcps" }

Plattform-Support

TierPlattformStatusCI
Tier-1Linux x86_64 (Ubuntu 24.04, Debian 12)✓ alle Testsjeder PR
Tier-1Linux aarch64 (Ubuntu 24.04)✓ alle Testsjeder PR
Tier-2macOS aarch64 (≥14.0)✓ manuell verifiziertrelease-cycle
Tier-2Windows x86_64 (≥10)✓ manuell verifiziertrelease-cycle
Tier-3FreeBSD 14, OpenBSD 7.5~ Best-Effort (community)
Tier-3RTOS/Embedded (no_std + alloc)~ Layer-1 only (foundation/cdr/qos/types)

Was als nächstes

  • Topic-Type via IDL: statt RawBytes typisierte Messages → idlc Compiler.
  • Cross-Process Pub/Sub: zwei cargo run-Prozesse auf gleicher Domain-ID, eine Maschine.
  • Cross-Vendor: ZeroDDS Subscriber gegen Cyclone DDS Publisher → siehe Transport-Tuning.
  • QoS-Tuning: nicht-Default-QoS für Late-Joiner, Failover, Realtime → QoS Cookbook.
  • Security aktivieren: --features securitySecurity Plugin-Chain.
Topic · Quickstart

Dev Install — first sample in 5 minutes

From an empty project to the first pub/sub roundtrip on loopback: a new Cargo project, three crates as a dependency, ~15 lines of code, cargo run. Then: feature-flag builds (why three?), dev toolchain, config knobs and platform support. This page is Rust-focused — for C++, C#, Java, Python, TypeScript or C-FFI see the language picker.

MSRV: Rust 1.88 · Edition 2024 Tier-1 platforms: Linux x86_64/aarch64 License: Apache 2.0

Which language?

ZeroDDS is pure Rust under the hood, with native bindings for 7 more languages. Each has its own 5-minute quickstart — install, pub/sub code, run.

LanguageInstallPrerequisitesSpecificsQuickstart
Rust (primary path)cargo add zerodds-dcpsRust 1.88+ · Edition 2024pure Rust · async/streams · no_std-capablebelow ↓
C++-lzerodds + headersC++17 · libzerodds.soDDS-PSM-Cxx 1.0 · ABI-stable · zerodds-idlc --cpp/bindings/cpp/ →
C# / .NETdotnet add package ZeroDDS.NET 8 + netstandard2.1NativeAOT · async/await · source generators/bindings/csharp/ →
JavaMaven / GradleJDK 17+ (21+ for virtual threads)pure Java · org.omg.dds.* · no JNI/bindings/java/ →
Pythonpip install zeroddsCPython 3.8–3.14 (abi3-py38)@idl_struct · AsyncIO · QoS builder/bindings/python/ →
TypeScript (Node)npm install @zerodds/nodeNode 18 LTS+N-API · strict TS · async/streams/bindings/typescript-node/ →
TypeScript (browser)npm install @zerodds/wasmChrome 89+ · Firefox 89+ · Safari 15+WASM · WebSocket bridge needed/bindings/typescript-wasm/ →
C-FFI-lzerodds + zerodds.hC99+ or C interopstable ABI · for Go, Zig, Ada, MATLAB, …/bindings/c-ffi/ →

The Rust page (below) is at the same time the pure-Rust stack overview — feature flags, dev toolchain, config, platform support. If you start in another language, go straight to the language page; most sections below it (config, platforms, dev toolchain) apply in parallel.

5-minute quickstart (Rust)

A new Cargo project, three dependencies, a publisher and a subscriber in the same process. Runs on any system with Rust 1.88+, no setup.

1 · Cargo project + dependencies

cargo new zerodds-hello --bin
cd zerodds-hello

Cargo.toml:

[package]
name = "zerodds-hello"
version = "0.1.0"
edition = "2024"

[dependencies]
zerodds-dcps = "1.0.0-rc.3"

That's all. zerodds-dcps pulls in all required layer crates transitively (foundation, cdr, qos, types, rtps, discovery, transport, transport-udp).

2 · First pub/sub loop

src/main.rs:

use std::time::Duration;
use zerodds_dcps::*;

fn main() -> Result<()> {
    let factory = DomainParticipantFactory::instance();
    let participant = factory.create_participant(0, DomainParticipantQos::default())?;

    let topic = participant.create_topic::<RawBytes>("Chatter", TopicQos::default())?;
    let publisher = participant.create_publisher(PublisherQos::default());
    let subscriber = participant.create_subscriber(SubscriberQos::default());

    let writer = publisher.create_datawriter::<RawBytes>(&topic, DataWriterQos::default())?;
    let reader = subscriber.create_datareader::<RawBytes>(&topic, DataReaderQos::default())?;

    writer.wait_for_matched_subscription(1, Duration::from_secs(5))?;
    reader.wait_for_matched_publication(1, Duration::from_secs(5))?;

    writer.write(&RawBytes::new(b"hello".to_vec()))?;
    reader.wait_for_data(Duration::from_secs(3))?;

    for sample in reader.take()? {
        println!("got: {:?}", sample.data);
    }
    Ok(())
}

▶ Runnable example: rust-dev-install-hello

3 · Build + run

cargo run --release

Expected output: got: [104, 101, 108, 108, 111] (the "hello" as bytes). If that runs, the stack is fully functional — discovery + RTPS + UDP loopback + DCPS API.

Cargo pulls the world first: ZeroDDS has ~90 workspace crates; the first cargo build compiles a few hundred MB of dependencies. Plan 1-2 min for the first build, then incremental runs in <1 s.

Feature flags — why three builds

ZeroDDS crates have three build profiles that serve different platform requirements. The default feature is std — the normal case for servers, desktops, containers.

FeatureDefault?PlatformWhat it givesWhen to use
stdLinux · macOS · Windows · *BSDFull standard library, thread pool, OS sockets, filesystem.Servers, desktops, containers — the normal case.
allocEmbedded with an allocator (Tock-OS, RTOS with alloc)Heap allowed (Vec, String), but no std (no threads, no FS).An MCU with an RTOS that provides an allocator. Cortex-M7/A-class.
safetyall (orthogonal to std/alloc)Extra runtime checks: panic-on-drift for internal invariants, strict bounds checks, tagged state machines.Compliance builds (CRA audit, ISO-26262 preparation), pre-production hardening.
(no default features)Freestanding · bare metal · #![no_std]Strict no_std, no heap. Only const-evaluable surfaces.Cortex-M0/M3-class without an allocator, RTOS kernel libraries.

Examples:

# server build (default)
zerodds-dcps = "1.0.0-rc.3"

# embedded with allocator (alloc + safety)
zerodds-foundation = { version = "1.0.0-rc.3", default-features = false, features = ["alloc", "safety"] }
zerodds-cdr        = { version = "1.0.0-rc.3", default-features = false, features = ["alloc"] }

# strict no_std (bare metal)
zerodds-foundation = { version = "1.0.0-rc.3", default-features = false }
zerodds-cdr        = { version = "1.0.0-rc.3", default-features = false }

Important: the full DCPS stack (zerodds-dcps) needs std (threads for discovery, OS sockets for UDP). The layer-1 crates (foundation, cdr, qos, types) are no_std-capable — for embedded you typically build in only the encoders/decoders and use an external transport bridge.

Dev toolchain

What you need on the dev system.

Rust

# rustup if not already there
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# set the MSRV explicitly (workspace value)
rustup install 1.88
rustup default 1.88

# components
rustup component add clippy rustfmt rust-src

System packages

ZeroDDS has very few system dependencies; most of it is pure Rust.

PlatformPackagesWhy
Ubuntu/Debianbuild-essential pkg-config libssl-devLinker, OpenSSL for DDS-Security tests
Fedora/RHELgcc pkg-config openssl-develditto
macOSXcode CLT (xcode-select --install)Linker, macOS SDK
WindowsVisual Studio Build Tools (C++ workload)MSVC linker

Optional — cross-vendor tests

# Linux: Cyclone DDS for live interop tests
sudo apt install cyclonedds-tools     # provides ddsperf, ddsls

# macOS via Homebrew
brew install cyclonedds

This enables the crates/discovery/tests/cyclone_live_* cross-vendor tests; without it they are skipped.

Editor setup

  • VS Code: the rust-analyzer extension. In the workspace it works out of the box (90+ crates index in ~30 s on first open).
  • JetBrains: RustRover or IntelliJ + the Rust plugin.
  • Vim/Neovim: rust-analyzer via an LSP client (coc.nvim, nvim-lspconfig).
  • Format on save: rustfmt with the workspace default (rustfmt.toml at the root).

Runtime config — what devs really tweak

Install isn't just the build — most problems arise at runtime configuration. What are the important knobs?

Domain ID

All participants in the same domain talk to each other; everything else is invisible. The default 0 is fine for dev — in production use a dedicated ID per tenant/stage:

let participant = factory.create_participant(42, DomainParticipantQos::default())?;

Port mapping follows DDSI-RTPS §9.6.1.4: port = 7400 + 250 * domain_id. The maximum domain ID is 232 (otherwise >65535 port).

Discovery multicast

SPDP uses multicast 239.255.0.1 by default. Works on a LAN out of the box. Problems: container networks (the Docker bridge blocks multicast), cross-subnet (router config needed), cloud VPC (no multicast).

If multicast doesn't work: a TCP backend + static peers (see Transport Tuning recipe 2).

Fast discovery for dev loops

The default discovery heartbeat is 1 s. Too slow for dev loops (run, write, exit, run). Fast mode:

use zerodds_dcps::runtime::RuntimeConfig;

let cfg = RuntimeConfig {
    tick_period: Duration::from_millis(20),
    spdp_period: Duration::from_millis(100),
    ..RuntimeConfig::default()
};
let participant = factory.create_participant_with_config(0, DomainParticipantQos::default(), cfg)?;

▶ Runnable example: rust-dev-install-runtimeconfig

That brings match latency under 200 ms. Not for production — 10× more discovery traffic.

Logging

ZeroDDS uses tracing. In dev:

# Cargo.toml
tracing-subscriber = "0.3"

# main.rs
fn main() {
    tracing_subscriber::fmt().with_max_level(tracing::Level::DEBUG).init();
    // ... rest
}

# CLI
RUST_LOG=zerodds=debug cargo run

Structured logging with span trees shows the discovery flow, sample path, retransmits.

QoS

Out of the box you get the DDS spec defaults (§2.2.3.14, see the QoS Reference): writer=Reliable, reader=BestEffort, History=KeepLast(1), Durability=Volatile. Because the reader requests BestEffort by default, effective delivery is best-effort — for guaranteed delivery, set the reader explicitly to Reliable. For state topics, add Durability=TransientLocal so late joiners see the last value. Ready-made profiles: QoS Cookbook.

Building from source

For contributing to the stack or local patches.

git clone https://github.com/zero-objects/zero-dds.git
cd zero-dds
cargo build --workspace --release
cargo test --workspace

Expectation:

  • First build: 5-10 min on an 8-core, depending on disk.
  • Incremental: <1 s per crate.
  • Full test suite: ~3-5 min (~5400 tests).

Pre-commit checks (run before every push):

cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo run -p dds-lint -- check crates/

Crates as a path dep for patches:

# Cargo.toml in the consuming project
[patch.crates-io]
zerodds-foundation = { path = "/home/you/zero-dds/crates/foundation" }
zerodds-dcps       = { path = "/home/you/zero-dds/crates/dcps" }

Platform support

TierPlatformStatusCI
Tier-1Linux x86_64 (Ubuntu 24.04, Debian 12)✓ all testsevery PR
Tier-1Linux aarch64 (Ubuntu 24.04)✓ all testsevery PR
Tier-2macOS aarch64 (≥14.0)✓ manually verifiedrelease cycle
Tier-2Windows x86_64 (≥10)✓ manually verifiedrelease cycle
Tier-3FreeBSD 14, OpenBSD 7.5~ best-effort (community)
Tier-3RTOS/embedded (no_std + alloc)~ layer-1 only (foundation/cdr/qos/types)

What next

  • Topic type via IDL: typed messages instead of RawBytes → the idlc compiler.
  • Cross-process pub/sub: two cargo run processes on the same domain ID, one machine.
  • Cross-vendor: a ZeroDDS subscriber against a Cyclone DDS publisher → see Transport Tuning.
  • QoS tuning: non-default QoS for late joiners, failover, real-time → QoS Cookbook.
  • Enable security: --features securitySecurity Plugin-Chain.