WebSocket

A WebSocket gives a program a persistent connection to mesgd's message router. The connection uses the main HTTPS port and a URL path describing the messages the program wants to receive. After the upgrade, the program sends JSON text frames; mesgd compares each message with the registered listener paths and delivers it to the matching listeners.

Authenticate the connection

mesgd accepts WebSocket version 13. A client that can set request headers sends Authorization: Bearer TOKEN on the upgrade request. A browser client supplies the credential as the second entry in its subprotocol list:

const socket = new WebSocket(
  'wss://mesgd.example.com:4433/kind=chat/room=lobby',
  ['json', token]
);
socket.onopen = () => socket.send(JSON.stringify({
  kind: 'chat', room: 'lobby', text: 'hello'
}));

Here, token is an existing login session or an issued grant token. The authentication layer recognizes the header form Sec-WebSocket-Protocol: json, TOKEN; the listener returns json as the selected protocol. Sending only json supplies no credential. A missing credential receives 401 unless the path is listed in public_paths or authentication has been disabled for a local test.

A login session proves identity and is accepted without a path list. A grant token must cover the connection path and remain assigned to an active user. Use a grant when the connection needs restricted routing access. Routing explains the token types and the checks applied during delivery.

Send JSON messages

For an ordinary connection, mesgd registers the URL path as a listener. A message such as {"kind":"chat","room":"lobby","text":"hello"} matches /kind=chat/room=lobby, so programs listening on that path can receive it. The sending socket can also receive its own message when its listener path matches.

Messages from a grant connection are filtered against the sender's current grants before matching listener paths. That delivery path also rechecks the receiving socket's credential. Messages from other connections use the generic listener scan. These are different delivery paths; a login session does not acquire grant restrictions merely because permissions have been assigned to its user.

Text frames must decode as JSON. Raw base64 ciphertext is not a valid replacement and causes the connection to fail. The listener fixes its text-message protocol to JSON rather than negotiating a different payload format. Paths under /agents/erlang have dedicated agent handlers instead of ordinary message listeners.

How the SDK samples differ

The SDK ping/pong samples describe another protocol. They sign a registration envelope with ECDSA P-256, encrypt it for an RSA public key, and send the base64 ciphertext as the first frame. Subsequent frames carry encrypted messages. mesgd does not decrypt that registration frame or complete the handshake, so these samples cannot currently establish an application session with this listener.

The /mesgd/pki HTTP mount also does not register keys; it logs the request and returns an empty response. Use PUT /auth/keys to publish account public keys. SDK keys describes the cryptographic formats, and Samples explains what the sample programs demonstrate.

The agent topics described in the SDK's bot.md are conventions between applications. mesgd does not reserve them or interpret their envelopes. They use ordinary routing unless they are one of the dedicated Erlang agent paths.