Skip to main content

Ways to run WAI

A live room runs on three open pieces: the relay (wai-relay), which carries every participant's tracks and their receipts; the room service (wai-room), which holds the room's keys, issues grants and signs the room's lifecycle; and the room client, the page a browser loads to join. All three are open source under Apache-2.0, come in the prebuilt release beside wai, and need no account. The quickstart installs them, prebuilt or from source.

On your own machine

wai create my-room --template video-room
cd my-room
wai dev

wai dev starts the relay and the room service on loopback ports of their own, makes the room's keys in .wai/dev/ the first time, and serves one origin, http://127.0.0.1:8080: your page at /, the room client beside it, the room service at /room-api/ and the relay's WebSocket binding at /moq. Open it in two tabs and press Join in each. wai dev --check starts the same, checks each piece through that origin, and stops.

On your own host

The same pieces run as two daemons behind a front of your own, each on its default from the port table. Run these in a directory of your own on the host.

1. The room's keys

wai-room keygen keys.toml > relay-lines.toml

keys.toml holds the room's authority and clock keys, readable by its owner alone (mode 0600); keep it out of every repository. The command prints the lines the relay needs to trust those keys, here into relay-lines.toml; wai-room relay-lines keys.toml prints them again.

2. The relay

relay.toml:

websocket_listen = "127.0.0.1:4480"
path = "/moq"

[receipts]
receipts_track_suffix = "_receipts"

[[receipts.door]]
prefix = ["*", "*", "audio"]
trust_field = 1
hold_ms = 2000

[[receipts.door]]
prefix = ["*", "*", "video"]
trust_field = 1
hold_ms = 2000

[auth]
required = true
cat relay-lines.toml >> relay.toml

The relay serves its WebSocket binding on loopback, for the front to carry. Each door holds a participant's audio and video to the key its namespace names, and [auth] required refuses a session that presents no grant. The relay's example configuration, relay.example.toml beside its source, shows every other field: QUIC and WebTransport on a UDP port with a certificate, the cache, the limits.

3. The room service

room.toml:

listen = "127.0.0.1:9682"
public_prefix = "/room-api"
keys = "keys.toml"
relay_url = "ws://127.0.0.1:4480/moq"

[room]
max_publishers = 4

The service answers on loopback, under the path the front serves it at (public_prefix), and its clock holds a session on the relay's WebSocket binding. room.example.toml, beside its source, shows every other field and every kind of room it keeps.

4. Start both

wai-relay --config relay.toml
wai-room --config room.toml

Once the room's clock holds its session on the relay, GET http://127.0.0.1:9682/health answers {"ok":true,"relay":true,"room":"<the room's id>"}.

5. The front

Your front holds the site's certificate and serves one origin, as wai dev does on your machine:

The room page refuses a service on another origin, which is why the three share one. A visitor's tab makes its own key, asks the room service for a grant at /room-api/grant, and proves the key to the relay over wss:// on your origin at /moq. The room service and the relay describes every route and how a client connects.