# Player WebSocket Reference ## Overview Player service websocket base URL: `ws://localhost:3001` This document uses OpenAPI-style sections, but stays in plain markdown. The `PULSE_SIGNAGE_SHARED_SECRET` setting does not change the websocket message format here. It is used to sign the player control socket URL and the server-side snapshot subscription; the message payloads themselves remain the same. ## Channels ### `GET /ws/screens/{slug}` Player control channel. This is the bidirectional socket used by the player page. The player sends status messages to the server, and the server sends commands back to the player. Access: the player page must include a valid `auth` query parameter signed with the shared secret. The browser page refreshes this token automatically while it is active. ### `GET /ws/screens/{slug}/events` Player snapshot channel. This is the server-to-dashboard snapshot stream for live player connection state. Access: internal-only. The web backend subscribes with signed request headers; browsers should not connect directly. ## Player Control Channel ### Messages from player to server The player sends two message types: - `hello` - `state` #### `hello` Example payload: ```json { "type": "hello", "clientId": "client-id", "clientName": "friendly label", "deviceId": "device-id", "userAgent": "browser ua", "page": "http://.../screen/demo", "viewport": { "width": 1920, "height": 1080 }, "paused": false, "blackout": false, "currentSlide": null } ``` #### `state` Example payload: ```json { "type": "state", "clientId": "client-id", "clientName": "friendly label", "deviceId": "device-id", "userAgent": "browser ua", "page": "http://.../screen/demo", "viewport": { "width": 1920, "height": 1080 }, "paused": false, "blackout": false, "currentSlide": { "id": 12, "title": "Main Slide", "kind": "image", "playlistSignature": "..." } } ``` The server recognizes `clientId`, `clientName`, `deviceId`, `userAgent`, `page`, `viewport`, `paused`, `blackout`, and `currentSlide` from player messages. When `currentSlide` is present, the player includes the active slide id, title, kind, and playlist signature. ### Messages from server to player The server sends command messages with: - `type: "command"` - `command` - optional `sentAt` - optional `targetConnectionId` - optional `blackout` for blackout commands - optional `url` for redirect commands - optional `clientName` and `deviceId` for client-name updates Supported commands: - `refresh` - `reload` - `redirect` - `pause` - `blackout` - `previous` - `next` - `left` - `right` - `setclientname` #### `refresh` Asks the player to refetch the current playlist. #### `reload` Forces a browser page reload. #### `pause` Toggles paused state on the player. #### `blackout` Sets blackout state explicitly. Example payload: ```json { "type": "command", "command": "blackout", "blackout": false } ``` Use `false` to restore and `true` to blackout. #### `redirect` Requests the player page to navigate to a new location. The destination is supplied as `url` by the caller that forwarded the command. #### `previous` / `left` Moves to the previous slide. #### `next` / `right` Moves to the next slide. #### `setclientname` Updates the client name associated with the player session and onboarding record. The command payload should include `clientName` and may include `deviceId` when the caller is updating a specific onboarding binding. ## Snapshot Channel ### Messages from server to client The server sends snapshot payloads on `/ws/screens/{slug}/events`. Example payload: ```json { "type": "snapshot", "slug": "demo", "connections": [], "sentAt": "2026-07-14T12:00:00.000Z" } ``` The snapshot channel is server-to-client only. ## Data Models ### Connection Snapshot - `id` - `clientId` - `clientName` - `deviceId` - `label` - `userAgent` - `viewport` - `page` - `currentSlide` - `currentSlideId` - `currentSlideTitle` - `paused` - `blackout` - `clientIp` - `remoteAddress` - `connectedAt` - `lastSeenAt` ### Command Message - `type` - `command` - `sentAt` - `targetConnectionId` - `blackout` ### Snapshot Message - `type` - `slug` - `connections` - `sentAt` ## Notes - This document covers only the player websocket channels. - Web UI/admin websocket behavior is intentionally omitted.