WebSockets

Composer ships an embedded WebSocket server that pushes real-time events to subscribed clients and accepts a small set of command messages. This page covers the connection model, the message envelope, the catalogue of message types, and the subscription channels.

Note — not available on Core licences

The WebSocket server is disabled at startup under a Vindral Composer Core (free) licence, regardless of the EnableWebSockets setting. No listener is opened on the configured port and clients will fail to connect. See Activating a license for licence-tier details.

Connection

Property Value
URL ws://{host}:{port}/
Default host localhost (configurable; see the Web API tab in Settings)
Default port 8081
Protocol RFC 6455 WebSocket; UTF-8 JSON text frames
TLS Not provided directly — terminate at a reverse proxy if needed

The server is off by default. Enable it via the EnableWebSockets setting (see the WebSockets section of the settings.xml reference). Restart Composer for the change to take effect — the WebSocket server is started during application startup.

On a successful handshake the server immediately sends a Welcome message containing the connection's assigned Guid. Clients should keep that GUID and quote it back in subsequent commands so the server can route replies.

Authentication

The WebSocket server does not perform API-key authentication itself. Treat its port as trusted: bind to localhost for local-only access, or restrict the listening interface to a private network and front it with a TLS-terminating proxy (nginx, Caddy, etc.) that handles auth.

Use the HTTP API's WebSocket management endpoints to enumerate or disconnect connected clients on demand — those are protected by the same apikey mechanism as the rest of the HTTP API.

Message envelope

Every frame sent in either direction is a JSON object with this shape:

{
  "Type":     "PropertyChanged",
  "Content":  "<payload — usually a JSON string or human-readable string>",
  "Guid":     "<connection / receiver guid>",
  "ObjectId": "<related object guid, or all-zero if not applicable>",
  "DateTime": "2026-04-29T13:42:18.0000000Z"
}

Type is one of the values in the table below (case-sensitive). Content is the actual payload — a plain string for system messages, a JSON-encoded inner document for PropertyChanged / MultiplePropertiesChanged / ComponentLogUpdate, etc. Guid is the connection's identity (server-assigned in the Welcome message) and ObjectId references a Composer object when relevant.

Message types

Defined in WebSocketServer.Enums.SocketMessageType.

Type Direction Description
Welcome server → client First message after handshake; carries the server-assigned connection GUID.
System both Generic system messages — server heartbeats, ping/pong, ack strings.
Subscribe client → server Subscribe to one of the channels listed in the next section.
Unsubscribe client → server Cancel a subscription. Content is the channel name (or All).
PropertyChanged server → client One property on one object changed. Content is a JSON document with object id, property name, new value.
MultiplePropertiesChanged server → client Several properties changed in the same tick — coalesced for efficiency.
SetPropertyValueByObjectId client → server Request a property value change. Content is a JSON document with the target object id, property name, and value.
ExecuteCommandByObjectId client → server Invoke a Command property on a target object.
AudioMixerSummary server → client Periodic audio-mixer levels snapshot for clients subscribed to AudioMixer.
LogMessage server → client Log entry for clients subscribed to LogFile.
ThumbnailUpdate server → client New input thumbnail for clients subscribed to thumbnail pushes.
ComponentLogUpdate server → client Component log entry for clients subscribed to ComponentLogs.
SystemInformationUpdate server → client Periodic CPU / memory / GPU stats for clients subscribed to SystemInformation.
Error server → client Server-side error in response to a malformed or rejected client message.

Subscription channels

Send a Subscribe message with Content set to one of these values to start receiving the matching push type. Channel names are case-insensitive on subscribe; Unsubscribe accepts the same names plus the wildcard All.

Channel Pushed message types Notes
AudioMixer AudioMixerSummary Throttled to the rate set by WebSocketThrottledPropertiesFrequency.
LogFile LogMessage Streams every log entry written by Composer's logger. Volume can be high under debug logging — consider scoping.
Components PropertyChanged for component status fields Tracks input/operator/target run state, errors, warnings.
ComponentLogs ComponentLogUpdate Per-component log entries (the same lines you'd see in the Desktop log panel for that component).
SystemInformation SystemInformationUpdate Periodic snapshot — CPU, RAM, GPU, frame budget, etc.
Thumbnails ThumbnailUpdate Pushed implicitly when an input registers for thumbnail updates; not a separate Subscribe channel today.

An Unsubscribe message with Content: "All" cancels every subscription on the connection.

Lifecycle events

The Runtime API broadcasts coarse lifecycle events (project start/stop/reload, runtime exit, etc.) to all WebSocket clients via the RuntimeEvent message type. The full event list lives on the Runtime API WebSocket Events page.

Configuration

All WebSocket-related settings live under the WebSockets section of settings.xml:

  • EnableWebSockets — master on/off switch.
  • WebSocketsHostName and WebSocketsPort — listening interface and port.
  • WebSocketsMaxConnectedSubscribers — connection cap (default 1).
  • WebSocketsMaxIncomingMessageQueueLength / WebSocketsMaxOutgoingMessageQueueLength — back-pressure tuning.
  • WebSocketThrottledPropertiesFrequency — how often coalesced pushes (audio mixer, property changes) emit.
  • WebSocketMsgAudioDecimals / WebSocketMsgAudioRmsDecimals — precision of audio level values to keep payloads small.

Quick start (browser JavaScript)

const ws = new WebSocket('ws://localhost:8081/');

ws.addEventListener('open', () => {
  // Subscribe to system info pushes.
  ws.send(JSON.stringify({ Type: 'Subscribe', Content: 'SystemInformation' }));
});

ws.addEventListener('message', (event) => {
  const msg = JSON.parse(event.data);
  switch (msg.Type) {
    case 'Welcome':
      console.log('Connected as', msg.Guid);
      break;
    case 'SystemInformationUpdate':
      console.log('System info:', JSON.parse(msg.Content));
      break;
    case 'Error':
      console.warn('Server error:', msg.Content);
      break;
  }
});