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.
Connect
Section titled “Connect”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 atokenparameter the connection is a liveness-only session: it is upgraded, answersping, and never receives an event.400- theUpgradeheader is missing or is notwebsocket.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);};Message envelope
Section titled “Message envelope”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.
Client messages
Section titled “Client messages”The server accepts exactly one client message:
ping- text frame. Answered with the text framepongon 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.
Close semantics
Section titled “Close semantics”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 lineWebSocket 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 thanping.- 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.
Configuration messages
Section titled “Configuration messages”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.
set-stream
Section titled “set-stream”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 forset-stream, the stored object withenableflipped fortoggle-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 thescanlist ofset-adapteris pushed the same way. Before pushing,set-streamadds the table version counters to the object:pmt_versionandsdt_versionfor an SPTS stream (1when the request had none, otherwise the request’s value plus one modulo 32),pat_version,cat_version,sdt_versionandnit_versionfor an MPTS stream (0when absent, otherwise plus one modulo 32).gid- number, present only in the message ofset-streamand only when the configuration holds agid. The object id counter the web interface keeps in the configuration, updated from the request’sgidwhen 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 thisidis no longer in the configuration.up- present when pushed byset-stream:truewhen the stream is being replaced and aset-streammessage with the new object follows,falsewhen it is removed. Absent when the removal is a side effect ofset-adapter(a stream whose only input was the removed adapter).
set-adapter
Section titled “set-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; fortoggle-adapterthe stored object withenableflipped.gid- number, present only in the message ofset-adapterand only when the configuration holds agid(seeset-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.
set-softcam
Section titled “set-softcam”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 agid(seeset-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.
set-cas
Section titled “set-cas”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 agid(seeset-stream).
Removal or replacement: {"scope": "set-cas", "cas": {"id": "a004", "remove": true, "up": false}}, with up as for set-adapter.
set-server
Section titled “set-server”Pushed by set-server.
{ "scope": "set-server", "id": 0, "server": { ... }}id- number, the zero-based position of the server in theserverslist of the configuration; absent when a new server was appended.server- the server entry as stored;{"remove": true}when the entry atidwas removed.
set-user
Section titled “set-user”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,2or3),enable,cipher(the password hash; the plainpasswordfrom 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 userset-userkeeps onlycipherfrom the stored entry, socreatedis present only when the request repeats it. Fortoggle-userit is the stored entry withenableflipped.{"remove": true}when the user was removed.
set-category
Section titled “set-category”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;groupsis 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.
set-auth
Section titled “set-auth”Pushed by set-auth.
{ "scope": "set-auth", "auth": { "enable": true }}auth- the HTTP authentication settings as stored (theauthobject of the request, withhttp_ip_allowandhttp_ip_denysorted by prefix length, the longest prefix first). Absent when the request had noauthobject.
set-config
Section titled “set-config”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.
set-settings
Section titled “set-settings”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 (seeset-stream).settings- the settings object as stored; absent when the request emptied it.
log_event
Section titled “log_event”Pushed by set-log.
{ "scope": "log_event", "set": { "api_access": true }}set- the log settings as stored.
stream_image
Section titled “stream_image”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- theurlfield of the request.
Status messages
Section titled “Status messages”adapter_status_update
Section titled “adapter_status_update”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,truewhile an adapter configuration uses it.
modulator_status_update
Section titled “modulator_status_update”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 inmodulator_listof Get status.busy- boolean,truewhile an output uses it.
license
Section titled “license”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, "expire": 1790000000, "origin": "https://..." }}Every field of license is optional and absent when unknown:
id- the first six characters of the serial number.type-1demo,2subscription,3corporate,4lifetime.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.