Tablebox DocsSite 日本語

Connecting

An app connects to Relay with a token its backend signs or with a link. The connection is a session rooted at a path of the project: the token or the link says where, and what the session may publish and read from there.

The Relay URL and transports

Relay serves MoQ at one URL over WebTransport, raw QUIC and WebSocket (QMux), with the same rules on each. The URL's path is ignored: the root comes from the token or the link.

Where Transport
Browsers WebTransport, falling back to WebSocket as the official MoQ client does: every WebKit browser (Safari, every iOS browser) uses WebSocket, and other engines use it when WebTransport is missing or loses a 500 ms race
Node WebTransport
Rust WebTransport for an https:// URL, raw QUIC for moqt:// or moql://

connection.transport says which one the session in use runs over: webtransport, websocket or quic.

Ways to connect

connect(options) returns a connection at once, with status connecting. Give the Relay URL and one of:

Option Meaning
token A token
getToken A function giving a token, called before every connection attempt
link, secret A link's ID and a secret. In browsers secret may be left out: the SDK makes one once per browser and keeps it in localStorage (tablebox.secret)
serverCertificateHashes The SHA-256 (hex) of a Relay certificate no authority signed, such as the local stack's

Tokens

A token is a JWT in the moq-auth 0.2.1 format, signed with HS256, HS384 or HS512 by a project key's secret, with the key's ID as the header's kid. It holds these claims and no others:

Claim Type Meaning
root path, default empty The session's root, relative to the project root
publish, subscribe lists of patterns, relative to root What the session may publish and read; at least one pattern in all
sub string, required The participant's ID, which removals name
iat seconds, required, at most 60 s ahead of Relay's clock When the token was issued, which removals and closings compare
exp seconds, required Checked when the session is admitted
nbf seconds, optional Checked when the session is admitted
{ "sub": "alice", "root": "rooms/42", "publish": ["alice/**"], "subscribe": ["**"], "iat": 1790000000, "exp": 1790000600 }

This token connects alice at rooms/42: she publishes under alice/ and reads everything beneath rooms/42; her paths, such as alice/camera.hang, are rooms/42/alice/camera.hang in the project. The ID a participant publishes under is what the issuer writes into publish; the write rights are what guarantee it. Two sessions with the same sub both stay.

Patterns follow moq-pattern: /-separated segments, each a literal, * (one whole segment), prefix*suffix (one segment) or ** (any number of segments, at most once). alice/** matches alice and everything beneath it, and ** every path. A malformed pattern is refused.

A session is told of every broadcast its subscribe patterns cover, and receives the tracks it reads. Someone who only reads adds nothing for anyone else, so a range with a few publishers and any number of readers costs each reader the same. In a range where many people publish, give each person a subscribe that names what they read, such as ["stage/**", ".aggregation/board"], and keep who is there in Aggregation's per-writer list: what each person receives then stays the same however many publish.

A link is made in Console or through the management API with a root and publish and subscribe patterns, in which a whole segment {id} stands for the joiner. Whoever holds its ID connects with a secret of 32 to 128 characters from A–Z a–z 0–9 - _, and is admitted with:

A link admits until it is deleted; deleting it closes its sessions with invalid-token.

Status and reconnecting

status is connecting (also while reconnecting), connected or closed; reason is why the last session ended when it carried a code and, once closed, why it closed. Both are signals: peek() reads them, subscribe() follows them.

exp is checked when a session is admitted, so a session carries on past it; getToken gives the next attempt a fresh token. Relay decides after the session opens, so a refused connection may show connected for a moment before it closes with its code. A Relay that shuts down sends each session a GOAWAY, and clients move to another Relay. A client that goes silent ends its session after 10 s, and its broadcasts end with it.

Codes

Code Name When What the SDK does
64 invalid-token The token or link is malformed, unknown or badly signed, carries another claim, lacks sub, iat or exp, or grants nothing; or its key or link was deleted Stops
65 expired exp has passed or nbf has not come Reconnects with a token from getToken
66 removed A removal covers the session Stops
67 closed A closing covers the session, or the project was deleted Stops
68 limit The project is stopped, or full for a new session Stops
69 unavailable This Relay has not yet read the project's state (a session waits up to 2 s for it) Retries

Reason is an Error with code and name; Reason.of(error) names a session close or a track error that carries one. Removals, closings and limits are in Managing projects; the codes of programs and other servers are in Serving.