WebSocket API
Wire Broker WebSocket
The sub, unsub and pub operations of the Wire Broker, the message delivery, and every reply and error, with frames.
Endpoint: wss://api.thuum.dev/api/{domain}/wire/connect?token=…. The connection needs a key linked to
a Wire Broker claim. Framing, refs and general errors are on WebSocket protocol.
The operations are the Event Broker's, without storage: nothing published here is kept.
Operations#
| Op | Fields | Flag | Reply |
|---|---|---|---|
sub | topic, ref? | S | sub:ok |
unsub | topic, ref? | — | unsub:ok |
pub | topic, type, data, ref? | P | pub:ok with id, ts |
The server pushes one more op, message, for each delivered message.
sub#
Subscribe to a topic and its whole subtree. Idempotent.
→ [{ "op": "sub", "topic": "plant", "ref": "1" }]
← [{ "op": "sub:ok", "topic": "plant", "ref": "1" }]From then on, every message published on plant or any plant:* topic arrives as a message.
Messages published before the sub:ok are gone: there is no history.
unsub#
Stop receiving a topic's messages. Idempotent, and needs no flag.
→ [{ "op": "unsub", "topic": "plant", "ref": "2" }]
← [{ "op": "unsub:ok", "topic": "plant", "ref": "2" }]pub#
Publish a message on exactly topic. The reply comes once it has been handed to the current
subscribers, and carries a random id and the server's ts. Nothing is stored under them.
→ [{ "op": "pub", "topic": "plant:line-3", "type": "readings", "data": { "t1": 71.4 }, "ref": "3" }]
← [{ "op": "pub:ok", "topic": "plant:line-3", "ref": "3", "id": "0f6c2a1e-3b7d-4e8a-9c41-2d5f8a7b6e10", "ts": 1792590697447 }]message#
One frame per delivered message, with the exact topic it was published on:
← [{ "op": "message", "id": "0f6c2a1e-3b7d-4e8a-9c41-2d5f8a7b6e10", "topic": "plant:line-3", "type": "readings", "data": { "t1": 71.4 }, "ts": 1792590697447 }]If the publishing connection is itself subscribed, it receives its message too.
Errors#
→ [{ "op": "pub", "topic": "plant:line-3", "type": "bad type", "data": 1, "ref": "4" }]
← [{ "op": "pub:error", "topic": "plant:line-3", "ref": "4", "code": "bad_request", "message": "type …" }]
→ [{ "op": "sub", "topic": "payroll", "ref": "5" }]
← [{ "op": "sub:error", "topic": "payroll", "ref": "5", "code": "forbidden", "message": "Missing S claim on topic" }]| Op | Possible codes |
|---|---|
sub | bad_request (invalid topic), forbidden |
unsub | bad_request (invalid topic) |
pub | bad_request, forbidden |
An unexpected server error closes the connection with code 1011 instead of replying: its details
are never logged, because they could hold your data. Reconnect.
With the client#
const socket = acme.wire.connect();
socket.onMessage((message) => console.log(message));
await socket.ready;
await socket.sub('plant');
const { id, ts } = await socket.pub('plant:line-3', 'readings', { t1: 71.4 });
await socket.unsub('plant');
socket.close();Failed ops reject with WireSocketError, whose code is one of the codes above, or closed if
the connection dropped first. See Sockets.