Binding · TypeScript (Browser/WASM)

TypeScript (Browser/WASM) — in 5 Minuten zum ersten Sample

ZeroDDS-Core kompiliert zu WebAssembly für Browser-Apps. Transport: WebSocket-Bridge (Browser haben keine UDP-Sockets). Setup: ZeroDDS WebSocket-Bridge auf dem Server, WASM-Modul im Browser, Pub/Sub wie überall.

Browser: alle mit WASM + WebSocket (Chrome 89+, Firefox 89+, Safari 15+) Install: npm install @zerodds/wasm Status: ✓ RC3 · WebSocket-Transport only

5-Minuten-Quickstart

Browser sieht keine UDP-Multicast-Discovery — eine WebSocket-Bridge auf dem Server schickt RTPS-Frames in beide Richtungen.

1 · WebSocket-Bridge starten (Server)

# im Repo
cargo run --release -p zerodds-websocket-bridge -- --listen 0.0.0.0:9001 --domain 0

2 · WASM-Modul installieren

npm install @zerodds/wasm

3 · Pub/Sub im Browser (app.ts)

import init, { DomainParticipantFactory } from '@zerodds/wasm';

async function main() {
    await init();    // WASM bootstrap

    const factory = DomainParticipantFactory.instance();
    const participant = await factory.createParticipantWebSocket('ws://localhost:9001', 0);

    const topic = participant.createBytesTopic('Chatter');
    const writer = participant.createPublisher().createBytesWriter(topic);
    const reader = participant.createSubscriber().createBytesReader(topic);

    await writer.waitForMatchedSubscription(1, 5000);
    await reader.waitForMatchedPublication(1, 5000);

    writer.write(new TextEncoder().encode('hello from browser'));

    await reader.waitForData(3000);
    for (const sample of reader.take()) {
        console.log('got:', new TextDecoder().decode(sample));
    }
}

main();

▶ Runnable example: typescript-wasm-quickstart

4 · Browser laden

npx vite       # oder dein Lieblings-Dev-Server
# öffne http://localhost:5173
# DevTools-Console: got: hello from browser

WebSocket-Bridge-Setup

Die Bridge wraps das WASM-Modul in einen WebSocket-Frame-Stream — jede RTPS-Submessage wird als binary frame versendet. Die Bridge selbst spricht UDP-RTPS gegen andere DDS-Peers im Netz.

# Bridge mit TLS (production)
zerodds-websocket-bridge \
    --listen 0.0.0.0:9001 \
    --domain 0 \
    --tls-cert /etc/zerodds/server.crt \
    --tls-key /etc/zerodds/server.key

Browser-Client nutzt dann wss://<host>:9001. Setup-Details: TLS-Reference, WebSocket-Bridge-Doc.

Bundler-Integration

Vite

// vite.config.ts
export default {
    optimizeDeps: { exclude: ['@zerodds/wasm'] },
    server: { fs: { allow: ['..'] } },
};

▶ Runnable example: typescript-wasm-vite-config

Webpack 5

// webpack.config.js
experiments: { asyncWebAssembly: true }

Next.js / Remix

Beide haben Built-in WASM-Support seit 2023. Import muss in einem 'use client'-Block (Next.js App Router) oder Browser-only-Component (Remix) stehen.

Browser-Limits

  • Kein UDP, kein Multicast: Discovery + Wire laufen über die WebSocket-Bridge.
  • Bundle-Size: WASM-Modul ist ~600 kB gzipped (≈2 MB unkomprimiert). Code-Splitting via import() empfohlen.
  • Kein DDS-Security im Browser: TLS terminiert in der WebSocket-Bridge; die Browser-Seite vertraut der Bridge.
  • Single-Threaded: WASM läuft auf dem Main-Thread (oder einem dedicated Worker). Keine echten OS-Threads.
Binding · TypeScript (browser/WASM)

TypeScript (browser/WASM) — first sample in 5 minutes

The ZeroDDS core compiles to WebAssembly for browser apps. Transport: a WebSocket bridge (browsers have no UDP sockets). Setup: a ZeroDDS WebSocket bridge on the server, the WASM module in the browser, pub/sub as everywhere.

Browser: any with WASM + WebSocket (Chrome 89+, Firefox 89+, Safari 15+) Install: npm install @zerodds/wasm Status: ✓ RC3 · WebSocket transport only

5-minute quickstart

The browser sees no UDP multicast discovery — a WebSocket bridge on the server sends RTPS frames in both directions.

1 · Start the WebSocket bridge (server)

# in the repo
cargo run --release -p zerodds-websocket-bridge -- --listen 0.0.0.0:9001 --domain 0

2 · Install the WASM module

npm install @zerodds/wasm

3 · Pub/sub in the browser (app.ts)

import init, { DomainParticipantFactory } from '@zerodds/wasm';

async function main() {
    await init();    // WASM bootstrap

    const factory = DomainParticipantFactory.instance();
    const participant = await factory.createParticipantWebSocket('ws://localhost:9001', 0);

    const topic = participant.createBytesTopic('Chatter');
    const writer = participant.createPublisher().createBytesWriter(topic);
    const reader = participant.createSubscriber().createBytesReader(topic);

    await writer.waitForMatchedSubscription(1, 5000);
    await reader.waitForMatchedPublication(1, 5000);

    writer.write(new TextEncoder().encode('hello from browser'));

    await reader.waitForData(3000);
    for (const sample of reader.take()) {
        console.log('got:', new TextDecoder().decode(sample));
    }
}

main();

▶ Runnable example: typescript-wasm-quickstart

4 · Load in the browser

npx vite       # or your favourite dev server
# open http://localhost:5173
# DevTools console: got: hello from browser

WebSocket bridge setup

The bridge wraps the WASM module in a WebSocket frame stream — each RTPS submessage is sent as a binary frame. The bridge itself speaks UDP RTPS to other DDS peers on the network.

# bridge with TLS (production)
zerodds-websocket-bridge \
    --listen 0.0.0.0:9001 \
    --domain 0 \
    --tls-cert /etc/zerodds/server.crt \
    --tls-key /etc/zerodds/server.key

The browser client then uses wss://<host>:9001. Setup details: TLS Reference, WebSocket bridge doc.

Bundler integration

Vite

// vite.config.ts
export default {
    optimizeDeps: { exclude: ['@zerodds/wasm'] },
    server: { fs: { allow: ['..'] } },
};

▶ Runnable example: typescript-wasm-vite-config

Webpack 5

// webpack.config.js
experiments: { asyncWebAssembly: true }

Next.js / Remix

Both have built-in WASM support since 2023. The import must be in a 'use client' block (Next.js App Router) or a browser-only component (Remix).

Browser limits

  • No UDP, no multicast: discovery + wire run over the WebSocket bridge.
  • Bundle size: the WASM module is ~600 kB gzipped (≈2 MB uncompressed). Code splitting via import() recommended.
  • No DDS-Security in the browser: TLS terminates in the WebSocket bridge; the browser side trusts the bridge.
  • Single-threaded: WASM runs on the main thread (or a dedicated worker). No real OS threads.