Pular para o conteúdo

Events API

Este conteúdo não está disponível em sua língua ainda.

The control server pushes live updates over a WebSocket channel: every configuration change made through the API and license state changes. The per-second statistics of streams and adapters are not pushed: they are read with the Monitoring method. The built-in web interface keeps its views current with this channel and Monitoring alone, so a custom interface can do the same: load the state once with the HTTP methods, then apply the messages of this channel and poll Monitoring once per second. The channel is one-directional apart from a liveness probe: the server never accepts commands over it.

Request: GET {control_path}control/event/?token=<token> with the header Upgrade: websocket

  • token - string, required to receive events. A one-time token issued by ws-token to the authenticated user; it is valid for 60 seconds and is consumed by the first handshake that presents it.

The credential is the token alone: a session cookie or an Authorization header on the handshake is ignored. The token is bound to the user who requested it, and both roles receive the same messages - an observer’s token admits the connection to every event listed on this page.

The handshake answers:

  • 101 - the connection is upgraded. With a valid token it is admitted into the broadcast set and receives every message below from that moment on. Without a token parameter the connection is a liveness-only session: it is upgraded, answers ping, and never receives an event.
  • 400 - the Upgrade header is missing or is not websocket.
  • 403 - the token is unknown, expired, already used, or its user has been disabled or removed since the token was issued. No session is opened.

Sec-WebSocket-Key is optional: when present the reply carries Sec-WebSocket-Accept, when absent the 101 goes out without it. Connection, Sec-WebSocket-Version and subprotocols are not checked. The scheme is ws://, or wss:// when the control server serves TLS (crt_chain and crt_key in the settings). With the --no-web-auth command line option every handshake is admitted without a token.

Nothing is replayed: a message pushed before the handshake completed is not delivered to the new connection, so a client loads the current state with the HTTP methods after every connect and reconnect. Every reconnect needs a fresh token.

Example, in a browser with a login session:

const { token } = await fetch("/control/", {
method: "POST",
body: JSON.stringify({ cmd: "ws-token" }),
}).then(r => r.json());
const ws = new WebSocket(`ws://server:8000/control/event/?token=${encodeURIComponent(token)}`);
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
console.log(msg.scope, msg);
};

Every server message is one text frame with a JSON object. The scope field names the message type; the other fields depend on the scope:

{
"scope": "set-stream",
"stream": { "id": "a001", "name": "...", "type": "spts", "enable": true, "input": [ "..." ] }
}

The one text frame without JSON is pong, the answer to the client’s ping. Messages are delivered in the order they were produced. A field that is unset in the configuration is absent from the message, never null, so a client checks for presence.

The server accepts exactly one client message:

  • ping - text frame. Answered with the text frame pong on the same connection. A liveness-only session (no token) gets the same answer.

A WebSocket ping control frame (opcode 9) is answered with a pong control frame carrying the same payload; it is not a client message and never closes the connection. Any other text frame closes the connection with code 1008. A binary frame, or a message larger than 256 KiB, ends the connection without a close code; a protocol violation such as an unmasked frame is answered with close code 1002.

The server sends no WebSocket ping frames of its own. A client that wants to detect a dead connection sends ping periodically and treats a late pong as a failure. Astra’s own peer monitor (the ws_monitor module, used by a fallback instance to watch its master) sends ping every second, expects pong within 3 seconds and reconnects one second after a failure.

  • 1001 - the server ends the session: the control server is shutting down (process exit, restart or configuration reload), or the client is too slow. A slow client is one whose unsent backlog exceeds 1 MiB; it is disconnected with the log line WebSocket client buffer full, slow client, disconnecting, and the messages that did not fit are lost.
  • 1002 - a protocol violation in a client frame.
  • 1008 - a client message other than ping.
  • A close frame from the client is not answered; the server drops the connection.

A connection stays open when its user is disabled, removed, or changes the password: those actions revoke the user’s login sessions and streaming sessions, not open WebSocket sessions. The next handshake of that user is refused with 403 at the token check.

Each configuration command that changes the configuration pushes a message with the resulting object, after the change is applied and before the configuration is saved. A client that issued the command receives the message too. Messages that say "remove": true carry only the identifier.

Pushed by set-stream, toggle-stream, and by set-adapter, set-softcam and set-category when a stream had to be changed because an adapter, a softcam or a category it referenced was renamed or removed.

{
"scope": "set-stream",
"gid": 466561,
"stream": { "id": "a001", "name": "...", "type": "spts", "enable": true, "input": [ "..." ] }
}
  • stream - the stream configuration as stored: the object from the request for set-stream, the stored object with enable flipped for toggle-stream, the rewritten stored object when an input address changed (dvb://<adapter id>, cam=<softcam id>) or a group assignment was dropped. A stream discovered by the scan list of set-adapter is pushed the same way. Before pushing, set-stream adds the table version counters to the object: pmt_version and sdt_version for an SPTS stream (1 when the request had none, otherwise the request’s value plus one modulo 32), pat_version, cat_version, sdt_version and nit_version for an MPTS stream (0 when absent, otherwise plus one modulo 32).
  • gid - number, present only in the message of set-stream and only when the configuration holds a gid. The object id counter the web interface keeps in the configuration, updated from the request’s gid when it carried one: a new id is this counter in base 36, and the counter is echoed so every connected interface continues from the same value.

Removal or replacement:

{
"scope": "set-stream",
"stream": { "id": "a001", "remove": true, "up": false }
}
  • remove - true, the stream with this id is no longer in the configuration.
  • up - present when pushed by set-stream: true when the stream is being replaced and a set-stream message with the new object follows, false when it is removed. Absent when the removal is a side effect of set-adapter (a stream whose only input was the removed adapter).

Pushed by set-adapter and toggle-adapter.

{
"scope": "set-adapter",
"gid": 466561,
"adapter": { "id": "a002", "name": "...", "enable": true, "adapter": 0 }
}
  • adapter - the adapter configuration as stored; for toggle-adapter the stored object with enable flipped.
  • gid - number, present only in the message of set-adapter and only when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-adapter", "adapter": {"id": "a002", "remove": true, "up": false}}. up is true when a message with the replacement follows, false when the adapter is removed. The dependent streams are pushed as set-stream messages after this one.

Pushed by set-softcam.

{
"scope": "set-softcam",
"gid": 466561,
"softcam": { "id": "a003", "name": "...", "type": "newcamd" }
}
  • softcam - the softcam configuration as stored.
  • gid - number, present when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-softcam", "softcam": {"id": "a003", "remove": true, "up": false}}, with up as for set-adapter. Streams whose inputs referenced the softcam follow as set-stream messages.

Pushed by set-cas.

{
"scope": "set-cas",
"gid": 466561,
"cas": { "id": "a004", "name": "..." }
}
  • cas - the CAS configuration as stored.
  • gid - number, present when the configuration holds a gid (see set-stream).

Removal or replacement: {"scope": "set-cas", "cas": {"id": "a004", "remove": true, "up": false}}, with up as for set-adapter.

Pushed by set-server.

{
"scope": "set-server",
"id": 0,
"server": { ... }
}
  • id - number, the zero-based position of the server in the servers list of the configuration; absent when a new server was appended.
  • server - the server entry as stored; {"remove": true} when the entry at id was removed.

Pushed by set-user (both the control command and the observer’s own-password variant) and toggle-user.

{
"scope": "set-user",
"id": "login",
"user": { "type": 1, "enable": true, "cipher": "...", "created": 1758240000 }
}
  • id - string, the login.
  • user - the user entry as stored: type (1, 2 or 3), enable, cipher (the password hash; the plain password from the request is never pushed) and the other fields of the request. created (Unix time) is set when the request creates the user; on an existing user set-user keeps only cipher from the stored entry, so created is present only when the request repeats it. For toggle-user it is the stored entry with enable flipped. {"remove": true} when the user was removed.

Pushed by the set-category command on the /control/ entry point.

{
"scope": "set-category",
"id": 0,
"category": { "name": "...", "groups": [ { "name": "..." } ] }
}
  • id - the zero-based index of the category the request addressed, as the request sent it (a number, or a string when the request sent a numeric string); absent when a new category was appended.
  • category - the category as stored; groups is always a list. {"remove": true} when the category was removed.

Streams whose group assignment in the renamed or removed category changed are pushed as set-stream messages before this one.

Pushed by set-auth.

{
"scope": "set-auth",
"auth": { "enable": true }
}
  • auth - the HTTP authentication settings as stored (the auth object of the request, with http_ip_allow and http_ip_deny sorted by prefix length, the longest prefix first). Absent when the request had no auth object.

Pushed by set-config.

{
"scope": "set-config",
"key": "...",
"data": { ... }
}
  • key - the configuration key that was set.
  • data - the value stored under it; absent when the key was cleared.

Pushed by set-settings. Astra restarts one second after the reply, so a client receives this message and then loses the connection.

{
"scope": "set-settings",
"gid": 466561,
"settings": { "control_path": "...", "http_server_name": "..." }
}
  • gid - the stored object id counter (see set-stream).
  • settings - the settings object as stored; absent when the request emptied it.

Pushed by set-log.

{
"scope": "log_event",
"set": { "api_access": true }
}
  • set - the log settings as stored.

Pushed by set-stream-image. Nothing is stored: the message relays a screenshot address to the connected interfaces.

{
"scope": "stream_image",
"channel_id": "a001",
"src": "http://..."
}
  • channel_id - the stream id from the request.
  • src - the url field of the request.

Pushed when an adapter configuration takes a DVB frontend into use or releases it (an adapter is started, stopped, toggled, removed or reconfigured).

{
"scope": "adapter_status_update",
"adapter": 0,
"device": 0,
"busy": true
}
  • adapter, device - numbers, the frontend /dev/dvb/adapterN/frontendM.
  • busy - boolean, true while an adapter configuration uses it.

Pushed when an output takes a modulator into use or releases it (a stream with a resi, tbs or it950x output is started or stopped).

{
"scope": "modulator_status_update",
"kind": "tbs",
"adapter": 0,
"device": 3,
"busy": true
}
  • kind, adapter, device - the modulator, as in modulator_list of Get status.
  • busy - boolean, true while an output uses it.

Pushed by the license engine when the license state changes: a license file could not be loaded, a check returned a different type, e-mail, expiry or cleared an error, or a license fault is reported.

{
"scope": "license",
"license": {
"id": "ABCDEF",
"type": 2,
"email": "[email protected]",
"expire": 1790000000,
"origin": "https://..."
}
}

Every field of license is optional and absent when unknown:

  • id - the first six characters of the serial number.
  • type - 1 demo, 2 subscription, 3 corporate, 4 lifetime.
  • email - the e-mail the license is registered to.
  • expire - Unix time; the expiration date, or the activation date for a lifetime license.
  • error_code - number, the current license fault; absent while the license is valid.
  • error_text - string, set when the license file could not be loaded.
  • origin - the license server that answered the last request.
  • offline_expire - Unix time at which the last answer stops holding while the license server is unreachable; absent while the server is reachable.