WebSocket Communication
Audience: End users, system administrators, technical stakeholders Last Updated: 2026-04-06 Version: 2.0.0
Table of Contents
- Overview
- Key Concepts
- What WebSocket Provides
- How It Works
- Real-Time Updates
- Connection Management
- Configuration
- Integration with Other Features
- Error Handling & Reliability
- Technical Specifications
- Security Considerations
- Troubleshooting
- Related Documentation
Overview
WebSocket communication enables real-time, bidirectional messaging between the Llamafin app and your Jellyfin server. Unlike traditional HTTP requests where the client must repeatedly ask for updates, WebSocket maintains a persistent connection that allows the server to push updates to the app instantly as they happen.
Why It Matters
Without WebSocket, the app would need to constantly poll the server for changes (e.g., "Has my library changed? Has anyone started playing music?"), wasting battery, network bandwidth, and server resources. WebSocket eliminates this inefficiency by allowing the server to notify the app immediately when something changes.
Key Benefits
| Benefit | Description |
|---|---|
| Instant Updates | Library changes, playback events, and user updates arrive in real-time |
| Battery Efficient | No polling required — the connection stays open with minimal keep-alive pings |
| Server Friendly | Reduces server load by eliminating repetitive status-check requests |
| Multi-User Aware | See what other users are doing on the same server (remote control, sessions) |
| Self-Healing | Automatically recovers library data if the connection drops and reconnects |
Key Concepts
What Is WebSocket?
WebSocket is a communication protocol that provides a full-duplex (two-way) communication channel over a single, long-lived connection. Think of it as a phone call (persistent, both parties can speak at any time) versus sending letters (request-response, one at a time).
How Llamafin Uses WebSocket
Llamafin uses WebSocket for five primary purposes:
- Library synchronisation: Receive instant notifications when new music is added, existing items are updated, or content is removed from your library
- User Data Updates: Stay in sync with your play state, favorites, and watched status across devices
- Session Awareness: Track active playback sessions on the server (useful for remote control and remote control)
- Server Health: Detect when the server is shutting down or restarting, providing a graceful user experience
- Connection Monitoring: Provide real-time connection status to the app's network management system
What WebSocket Is NOT Used For
WebSocket is not used for:
- Music Streaming: Audio is streamed via HTTP with HLS (HTTP Live Streaming)
- Initial Library Loading: Library data is fetched via REST API on demand
- P2P Remote Control: The Llamafin Connect (P2P) feature uses separate encrypted channels, not this WebSocket
- Settings Sync: Settings are stored locally, not synced via WebSocket
What WebSocket Provides
Real-Time Notifications
When events occur on your Jellyfin server, the server pushes notifications to the app through the WebSocket connection:
| Event Type | What Triggers It | What the App Does |
|---|---|---|
| New Music Added | Server scans and imports new albums/songs | Fetches details for new items, updates library views, shows notification |
| Music Updated | Metadata changes (tags, artwork, etc.) | Fetches updated details, refreshes affected views |
| Music Removed | Content deleted from library | Removes items from all local library views |
| Folder Structure Changed | Library folders reorganized | Updates folder browsing navigation |
| User Data Changed | Play state, favorites, or ratings updated on another device | Syncs local data with server changes |
| Session Changed | Playback starts/stops on any device | Updates remote control session list |
| User Profile Updated | Account details modified | Refreshes user profile data |
| Server Shutting Down | Administrator restarts or stops server | Shows user-friendly "server shutting down" alert |
| Server Restart Required | Server needs restart after update | Flags that a restart is pending |
Connection Status Tracking
The app continuously monitors the WebSocket connection status and surfaces it through the unified network status system:
| Status | What It Means | User Experience |
|---|---|---|
| Connected | Real-time updates are flowing normally | Library updates arrive instantly |
| Connecting | App is establishing a new connection | Brief delay before real-time updates resume |
| Disconnected | No active WebSocket connection | Updates will arrive when connection restores |
| Error | Connection failed due to an error | App will retry when conditions change |
How It Works
Connection Lifecycle
┌─────────────────────────────────────────────────────────────────┐
│ WEBSOCKET CONNECTION LIFECYCLE │
└─────────────────────────────────────────────────────────────────┘
1. USER LOGS IN / SESSION READY
│
├── App validates: server URL, auth token, device ID, network status
├── If offline: connection attempt is skipped (saves battery)
└── If all checks pass: app builds WebSocket URL and connects
│
2. CONNECTION ESTABLISHED
│
├── Server confirms connection
├── App fetches fresh user profile data
├── App begins sending keep-alive pings every 10 seconds
└── Real-time updates begin flowing
│
3. SERVER PUSHES UPDATES (ongoing)
│
├── Library changes → app updates relevant views
├── User data changes → app syncs play state/favorites
├── Session changes → app updates remote control status
└── Server shutdown → app shows friendly alert message
│
4. CONNECTION ENDS
│
├── User logs out → app cleanly closes connection
├── Device goes offline → app closes connection to save resources
├── Server shuts down → connection drops, app notifies user
└── Network blip → connection drops (no automatic reconnect)
Keep-Alive Mechanism
To prevent the connection from being closed by proxies, load balancers, or the server itself due to inactivity, the app sends a lightweight "keep-alive" ping every 10 seconds. This is similar to occasionally saying "I'm still here" during a phone call to keep the line open.
Impact: Negligible bandwidth (~50 bytes every 10 seconds, or ~432 KB per day).
Message Routing
When the server sends a message, the app acts as a smart router:
- Receives the raw message from the WebSocket connection
- Identifies the message type (library change, user data change, etc.)
- Routes it to the appropriate feature within the app
- Reacts accordingly (fetches new data, updates the UI, shows a notification)
This ensures that each part of the app only handles the messages relevant to it, keeping the system organised and efficient.
Real-Time Updates
Library Updates
When your Jellyfin server adds, updates, or removes library content, the app receives granular notifications with item IDs rather than generic "something changed" messages.
Small Updates (50 items or fewer):
- App fetches details only for the changed items
- Updates specific sections of the library views
- Shows a rich notification describing the change
Large Updates (more than 50 items):
- App recognises this as a major library change
- Refreshes the "recently added" and "recently played" views entirely
- Shows a general notification about library updates
This threshold-based approach ensures efficiency: small updates are handled surgically, while large updates trigger a broader refresh.
User Data Sync
If you mark a song as favorite, change its play state, or update its rating on one device, those changes are instantly reflected on all your other devices through WebSocket push notifications.
Use Case: You're listening on your phone and mark an album as favorite. When you open the app on your tablet, that album is already favorited — no manual refresh needed.
Session Awareness
The app tracks active playback sessions across all devices connected to your Jellyfin server. This powers:
- Remote Device Control: See what's playing on other devices
- Remote Control: Control playback on another device from your current device
- Activity Monitoring: Know which users are actively listening
Connection Management
When Connections Are Established
| Trigger | Description |
|---|---|
| Successful Login | After you authenticate with your Jellyfin server |
| Session Rehydration | When the app restores your session on startup |
| Manual Reconnect | When you explicitly trigger a reconnect from settings |
| Server URL Change | After you switch to a different server (disconnects first, then reconnects to new server) |
When Connections Are Closed
| Trigger | Description |
|---|---|
| User Logout | Clean disconnect when you sign out |
| Session Expired | Server invalidates your session token |
| Device Goes Offline | Network loss, airplane mode, or force offline mode enabled |
| Server Shutdown | Server stops or restarts |
| Server URL Change | Disconnects from old server before connecting to new one |
Reconnection Behaviour
Important: The WebSocket system does not automatically reconnect after unexpected disconnects (e.g., network blips, server restarts). Reconnection requires one of the following:
- Manual Reconnect: You can trigger a reconnect from the network settings
- Re-authentication: Logging in again will establish a new connection
- Network Recovery + App Resume: When the network returns and the app re-validates your session
This is a known limitation. The app compensates with self-healing mechanisms (see below).
Self-Healing Mechanisms
Even without automatic reconnection, the app includes several self-healing features:
| Mechanism | How It Works |
|---|---|
| Library Recovery on Reconnect | When a connection is re-established, the app checks if library data is empty. If so, it automatically reloads the library from the server. |
| Connection Status Notifications | The app notifies you when the connection is lost and when it's restored (with debouncing to avoid spam). |
| Server Shutdown Alerts | If the server signals an intentional shutdown, the app shows a specific, user-friendly alert rather than a generic "offline" message. |
| Offline Gatekeeper | If the device is offline when a connection attempt is made, the app skips the attempt entirely (saves battery and prevents errors). |
Configuration
User-Facing Settings
WebSocket behaviour is mostly automatic and not directly configurable by users. However, some settings indirectly affect WebSocket:
| Setting | Location | Effect on WebSocket |
|---|---|---|
| Server URL | Settings → Source | Determines which server to connect to |
| Force Offline Mode | Settings → Network | When enabled, WebSocket connection is closed and not attempted |
| Network Detection | Automatic | App monitors network status and manages WebSocket accordingly |
Developer/Advanced Configuration
| Parameter | Value | Description |
|---|---|---|
| Keep-Alive Interval | 10 seconds | Frequency of ping messages to keep connection alive |
| Update Threshold | 50 items | Boundary between targeted and bulk library updates |
| Notification Debounce | 5 seconds | Minimum time between connection status notifications |
| Protocol Derivation | HTTP → WS, HTTPS → WSS | WebSocket protocol is derived from server URL protocol |
Integration with Other Features
Library Management
WebSocket is the primary trigger for library updates. When the server signals that items have been added, updated, or removed, the library feature reacts by:
- Fetching fresh data for the affected items
- Updating the local state (store)
- Refreshing the UI to reflect changes
- Showing a notification to the user
Without WebSocket, the library would only update when you manually refresh or navigate to a different view.
Authentication
After a successful login and WebSocket connection, the app fetches your full user profile to ensure it has the latest data. When you log out, the WebSocket connection is cleanly closed to prevent stale connections.
Network Management
The WebSocket connection status is fed into the app's unified network status system, which combines:
- Device network connectivity (WiFi/cellular/offline)
- Server reachability
- WebSocket connection status
This unified view powers the app's "online/offline" indicators and gates API calls appropriately.
Notifications
The app monitors WebSocket connection status changes and shows user notifications:
- "Connection restored" when the connection is re-established
- "Connection lost" when the connection drops
These notifications are debounced (5-second delay) to prevent spam during unstable network conditions. The first connection during app startup is suppressed (no notification).
Remote Device Control
WebSocket session updates inform the app about active playback sessions on other devices. This powers the remote control feature, allowing you to see and control what's playing elsewhere.
Error Handling & Reliability
What Happens When Things Go Wrong
| Scenario | App Behaviour | User Impact |
|---|---|---|
| Network drops | WebSocket closes, app enters offline mode | Real-time updates pause until network returns |
| Server restarts | Connection drops, app shows "server shutting down" alert | Brief interruption, updates resume after server is back |
| Server URL changes | Old connection closed, new connection established | Brief pause during transition |
| Token expires | Connection fails, app prompts for re-authentication | Must log in again to restore real-time updates |
| Large library change | App detects >50 items and refreshes entire views | Slightly longer update process, but complete |
| Message parsing fails | App logs error, connection stays open | Single message lost, subsequent messages work normally |
Graceful Degradation
The app is designed to function without WebSocket. If the connection fails or is unavailable:
- Library browsing still works (data is cached locally)
- Music playback still works (uses HTTP streaming, not WebSocket)
- Search still works (REST API calls)
- Settings still work (stored locally)
The only functionality lost is real-time updates. You can still manually refresh views to see the latest data.
Resource Management
| Resource | Management Strategy |
|---|---|
| Battery | Offline gatekeeper prevents connection attempts when device is offline |
| Network | Keep-alive pings are minimal (~50 bytes every 10 seconds) |
| Memory | Single WebSocket connection, cleaned up on disconnect |
| Server Load | No polling — server pushes updates only when needed |
Technical Specifications
Connection Details
| Specification | Value |
|---|---|
| Protocol | WebSocket (RFC 6455) |
| Secure Protocol | WSS (WebSocket Secure over TLS) when server uses HTTPS |
| Port | Same as server HTTP/HTTPS port (8096 default for Jellyfin) |
| Authentication | Query parameter (api_key) with user access token |
| Device Identification | Query parameter (deviceId) with unique device UUID |
| Connection URL Pattern | [ws/wss]://[server-host]:[port]/socket?api_key=[TOKEN]&deviceId=[UUID] |
| Keep-Alive Interval | 10 seconds |
| Keep-Alive Message | { "MessageType": "KeepAlive", "Data": {} } |
Message Types
The app handles 8 of 17 known server message types:
| Handled Types | Unhandled Types (ignored) |
|---|---|
| LibraryChanged | PackageInstallationCompleted |
| UserDataChanged | PackageInstallationFailed |
| Sessions | PackageInstalling |
| UserUpdated | GeneralCommand |
| UserDeleted | Play |
| ServerRestarting | PlayState |
| ServerShuttingDown | PlayStateCommand |
| RestartRequired | SyncPlayCommand |
| KeepAlive (server response to client ping) |
State Tracking
| Property | Possible Values |
|---|---|
| Connection Status | disconnected, connecting, connected, error |
| Error Message | null (no error) or string describing last error |
Performance Characteristics
| Metric | Value |
|---|---|
| Connection Setup Time | Typically < 500ms on stable network |
| Message Delivery Latency | Typically < 100ms from server event |
| Keep-Alive Bandwidth | ~432 KB per day |
| Memory per Connection | Minimal (single socket, no message buffering) |
| Max Concurrent Connections | 1 per app instance |
Security Considerations
Authentication Security
- Token in URL: The authentication token is passed as a URL query parameter. While convenient, this means the token appears in browser dev tools and server logs.
- Transport Security: When connecting to an HTTPS server, the WebSocket connection uses WSS (WebSocket Secure), which encrypts all traffic via TLS.
- No Additional Encryption: Unlike the P2P remote control feature (which uses ECDH key exchange + AES-256-GCM encryption), the WebSocket connection itself has no additional encryption beyond TLS.
Best Practices for Users
- Use HTTPS: Always connect to your Jellyfin server via HTTPS to ensure WebSocket traffic is encrypted (WSS)
- Secure Your Server: Ensure your Jellyfin server is properly secured with strong passwords and, if exposed to the internet, a reverse proxy with TLS
- Monitor Sessions: Regularly check active sessions in Jellyfin to detect unauthorized access
Known Limitations
| Limitation | Risk Level | Description |
|---|---|---|
| Token in URL query parameter | Low-Medium | Token visible in server logs and browser dev tools |
| No token refresh | Medium | If token expires, WebSocket silently fails until re-authentication |
| No certificate pinning | Low | App accepts any valid TLS certificate (vulnerable to MITM if CA is compromised) |
| No automatic reconnection | Low | User must manually reconnect after unexpected disconnects |
Troubleshooting
Common Issues
| Issue | Likely Cause | Solution |
|---|---|---|
| Real-time updates not working | WebSocket connection not established | Check network connection, verify server URL, try manual reconnect |
| Library not updating automatically | Server not sending WebSocket notifications | Verify Jellyfin server WebSocket is enabled and accessible |
| "Connection lost" notification | Network drop or server restart | Wait for network to recover, or manually reconnect |
| "Server shutting down" alert | Server administrator is restarting | Wait for server to come back online |
| Connection fails after server URL change | Old connection still active | Wait a moment for reconnect, or manually reconnect |
Diagnostic Steps
If real-time updates are not working:
- Check Network Status: Ensure your device has an active internet connection
- Verify Server URL: Confirm the server URL in Settings → Source is correct and accessible
- Check Server Status: Ensure your Jellyfin server is running and WebSocket is enabled
- Try Manual Reconnect: Use the network settings to trigger a manual reconnect
- Re-authenticate: Log out and log back in to establish a fresh connection
When to Seek Help
Contact support if:
- WebSocket connection consistently fails despite correct server URL and network connectivity
- Real-time updates work on some devices but not others (may be server configuration issue)
- You see frequent "Connection lost" notifications on stable networks
Related Documentation
- Authentication - How user sessions and tokens work
- Library Management - How library updates are processed
- Network Management - How network status is monitored and managed
- Remote Device Control - How session tracking enables multi-device playback
- Security Implementation - Security architecture and threat model
- Llamafin Connect (P2P) - P2P remote control (separate from WebSocket)
Last Updated: 2026-04-06 Version: 2.0.0