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:
- your page at
/(the projectwai createmade), with the room client from the release'sshare/wai/web/for every path your page does not hold; /room-api/handed to127.0.0.1:9682, with that prefix taken off;- a WebSocket upgrade at
/moq, subprotocolmoqt-22, handed to127.0.0.1:4480.
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.