Corbie

Plugins

websocket

This plugin opens a WebSocket connection, which carries messages in both directions.

websocket.connect(address, { headers, timeout })returns a connection, ws ws.send(message, { timeout })sends text or a handle as text, bytes or a blob as binary ws.receive({ timeout })returns the next message as text or bytes, or null ws.close()closes the connection

address is a URL that starts ws:// or wss://. The plugin percent-encodes its spaces, its non-ASCII characters and the characters a path cannot contain, and keeps an escape already in it, such as %2F.

Options:

headersheaders for the request that opens the connection, sent as written; a value may be a handle to a secret timeoutseconds, or text such as "5m"; default 30s
  • A script cannot set Host, Connection, Content-Length, Transfer-Encoding, Trailer, Upgrade, Sec-WebSocket-Key or Sec-WebSocket-Version.
  • The plugin reads messages and answers pings while the script does other work, and pings the other side every 30 seconds.
  • receive returns messages in the order they arrived, and null once the other side has closed the connection.
  • The plugin keeps up to 256 unread messages, and reads no more until the script receives one.
  • The plugin follows no redirect.

Errors:

timeoutthe call waited past its timeout; after a receive the connection stays open and no message is lost refusedthe connection could not be opened, or it broke not_foundthe host's name could not be resolved

Needs net:host for the host connected to. To send a handle in a header or a message, the job needs one of these.

secret:NAME@net:hostover wss:// secret:NAME@net.unencrypted:hostover ws:// too

This script sends a token in a header, subscribes and returns the first message.

allow: [net:feed.example.com, "secret:FEED_TOKEN@net:feed.example.com"]

const ws = websocket.connect("wss://feed.example.com/v1", {
  headers: { Authorization: secrets.text`Bearer ${secrets.get("FEED_TOKEN")}` },
})
ws.send(JSON.stringify({ subscribe: "prices" }))
const first = JSON.parse(ws.receive())
ws.close()
return first                        // gives { prices: { tea: 4.2, cake: 3 } }