Edit this page

You use the WebSocket binding to send Ditto Protocol messages over a persistent, duplex connection – enabling real-time change notifications, bidirectional messaging, and live device interaction.

TL;DR: Connect to ws://localhost:8080/ws/2, send Ditto Protocol JSON messages, and subscribe to events, messages, or live commands using plain-text control messages like START-SEND-EVENTS.

Overview

The WebSocket binding provides an alternative to the HTTP API for managing digital twins. Compared to HTTP, the WebSocket offers:

  • Lower overhead – a single persistent connection eliminates per-request HTTP handshake costs
  • Duplex communication – you receive change notifications, messages, and live commands/events on the same connection
  • Higher throughput – no HTTP header overhead means more commands per second

Every connected WebSocket session receives all events and messages it is authorized to see. There is no round-robin dispatching across sessions with the same authentication.

How it works

Send commands and receive responses

Send a Ditto Protocol command as a JSON message and receive a corresponding response. Match responses to requests using the correlation-id header. See Protocol examples for command/response patterns.

Subscribe to change notifications

After subscribing, you receive events whenever other clients modify Things, Features, or other entities you have read access to.

Subscribe to messages

Messages can be sent via both the HTTP API and WebSocket, but you can only receive and reply to messages through the WebSocket.

Subscribe to live commands and events

Use the WebSocket to receive live commands and events. The Ditto Protocol messages are the same as for the twin channel, but with live as the channel in the topic.

Setup

Endpoint

ws://localhost:8080/ws/2

Authentication

Authenticate using:

  • HTTP Basic Authentication with a username and password managed by your reverse proxy (e.g., nginx)
  • JSON Web Token (JWT) issued by an OpenID Connect provider

See Authentication for details.

WebSocket protocol format

A Ditto Protocol message over WebSocket combines all protocol fields into a single JSON object:

{
  "topic": "<the topic>",
  "headers": {
    "correlation-id": "<a correlation-id>",
    "a-header": "<header value>"
  },
  "path": "<the path>",
  "value": {}
}

See the Protocol specification for details on topic, headers, path, value, and status.

Subscription control messages

The WebSocket binding defines plain-text control messages (not JSON) for subscribing to different event streams.

Control message reference

Description Subscribe Unsubscribe Acknowledgment
Thing change notifications START-SEND-EVENTS STOP-SEND-EVENTS START-SEND-EVENTS:ACK / STOP-SEND-EVENTS:ACK
Messages START-SEND-MESSAGES STOP-SEND-MESSAGES START-SEND-MESSAGES:ACK / STOP-SEND-MESSAGES:ACK
Live commands START-SEND-LIVE-COMMANDS STOP-SEND-LIVE-COMMANDS START-SEND-LIVE-COMMANDS:ACK / STOP-SEND-LIVE-COMMANDS:ACK
Live events START-SEND-LIVE-EVENTS STOP-SEND-LIVE-EVENTS START-SEND-LIVE-EVENTS:ACK / STOP-SEND-LIVE-EVENTS:ACK
Policy announcements START-SEND-POLICY-ANNOUNCEMENTS STOP-SEND-POLICY-ANNOUNCEMENTS START-SEND-POLICY-ANNOUNCEMENTS:ACK / STOP-SEND-POLICY-ANNOUNCEMENTS:ACK
Refresh JWT authentication JWT-TOKEN

JWT token refresh

Ditto closes WebSocket connections when the JWT expires. To keep the connection open, send a new valid JWT using the JWT-TOKEN message. The sub claim of the new token must match the original token.

JWT-TOKEN?jwtToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Enrichment

Add extra fields to outgoing messages using the extraFields parameter on subscription messages:

START-SEND-EVENTS?extraFields=attributes/counter,features/ConnectionStatus
START-SEND-MESSAGES?extraFields=attributes

Enrichment is supported for all subscription types except Policy announcements. See enrichment for details.

Subscription type Enrichment supported
Thing change notifications Yes
Messages Yes
Live commands Yes
Live events Yes
Policy announcements No

Filtering

You can filter which events you receive by namespace or RQL expression. Specify parameters like HTTP query parameters, with ? for the first and & for subsequent ones. URL-encode filter values before use.

START-SEND-EVENTS?namespaces=org.eclipse.ditto&filter=gt(attributes/counter,42)
Subscription type Filter by namespace Filter by RQL
Thing change notifications Yes Yes
Messages Yes No
Live commands Yes No
Live events Yes Yes
Policy announcements Yes No

You can combine filtering with enrichment:

START-SEND-EVENTS?extraFields=attributes&filter=gt(attributes/counter,42)

Further reading

Tags: protocol http rql