Real-Time Updates
Deckyard uses Server-Sent Events (SSE) for real-time updates across the platform.
Overview
Section titled “Overview”Real-time features keep your presentations in sync across devices and users. SSE provides efficient, one-way streaming of events from the server to connected clients.
Features
Section titled “Features”Presentation Sessions
Section titled “Presentation Sessions”During live presentations:
- Slide sync - Audience follows presenter’s current slide
- Step sync - Animated builds stay in sync
- Control state - Enable/disable audience control
Collaboration
Section titled “Collaboration”During editing:
- Presence indicators - See who’s editing
- Slide locks - Know when slides are being edited
- Comment notifications - Instant new comment alerts
- Activity updates - Real-time activity feed
Interactive Elements
Section titled “Interactive Elements”For audience participation:
- Poll results - Live vote counts
- Q&A updates - New questions appear instantly
- Feedback submission - Real-time response collection
How It Works
Section titled “How It Works”Connection Lifecycle
Section titled “Connection Lifecycle”- Connect - Client opens SSE connection to server
- Subscribe - Client subscribes to relevant channels
- Receive - Server pushes events as they occur
- Heartbeat - Keep-alive pings maintain connection
- Disconnect - Connection closed on navigation/timeout
SSE Protocol
Section titled “SSE Protocol”Server sends events in this format:
event: statedata: {"slideIndex":3,"slideId":"abc123"}
event: controlEnableddata: {"controlEnabled":true,"updatedAt":1705312200000}Heartbeats
Section titled “Heartbeats”Every 30 seconds, the server sends a heartbeat comment to keep connections alive:
: heartbeatThis prevents proxies and browsers from closing idle connections.
Event Types
Section titled “Event Types”Session Events
Section titled “Session Events”| Event | Payload | Description |
|---|---|---|
state | { slideIndex, slideId, slideType, stepIdx } | Current presentation state |
controlEnabled | { controlEnabled, updatedAt } | Audience control toggle |
branch | { slideId, onClose } | Navigate to branched slide |
deckUpdated | { presentationId, slideId, reason } | Presentation content changed |
interactionState | { ... } | Poll/Q&A state updates |
Collaboration Events
Section titled “Collaboration Events”| Event | Payload | Description |
|---|---|---|
presence | { users } | Active collaborators |
lock | { slideId, email } | Slide edit lock acquired |
unlock | { slideId } | Slide edit lock released |
comment | { commentId, slideId } | New comment added |
Client Integration
Section titled “Client Integration”JavaScript Example
Section titled “JavaScript Example”// Connect to SSE endpointconst eventSource = new EventSource('/api/present/session/ABC123/events');
// Listen for state changeseventSource.addEventListener('state', (event) => { const state = JSON.parse(event.data); console.log('Now on slide:', state.slideIndex); navigateToSlide(state.slideId);});
// Handle errorseventSource.onerror = (error) => { console.error('SSE connection error:', error); // Implement reconnection logic};
// Clean up on page unloadwindow.addEventListener('beforeunload', () => { eventSource.close();});Reconnection
Section titled “Reconnection”SSE has built-in reconnection, but you can customize:
let retryCount = 0;const maxRetries = 5;
function connect() { const eventSource = new EventSource('/api/present/session/ABC123/events');
eventSource.onopen = () => { retryCount = 0; // Reset on successful connect };
eventSource.onerror = () => { eventSource.close(); if (retryCount < maxRetries) { retryCount++; setTimeout(connect, Math.pow(2, retryCount) * 1000); } };}Session Management
Section titled “Session Management”Creating Sessions
Section titled “Creating Sessions”When you start presenting:
- Server creates a presentation session
- Generates short follow codes (per language)
- Returns session ID and follow URLs
// Start a presentation sessionconst response = await fetch('/api/present/session', { method: 'POST', body: JSON.stringify({ presentationId: 'abc123' })});const { sessionId, followCodes } = await response.json();Session State
Section titled “Session State”Each session tracks:
- Current slide (index and ID)
- Step index (for animated builds)
- Control enabled/disabled
- Connected clients
- Last activity timestamp
Session Expiry
Section titled “Session Expiry”Sessions expire after inactivity:
- Default TTL: 30 minutes
- Activity resets the timer
- Expired sessions are cleaned up automatically
Follow Codes
Section titled “Follow Codes”Generation
Section titled “Generation”Short 4-character codes make joining easy:
https://your-instance.com/goCode: ABCDPer-Language Codes
Section titled “Per-Language Codes”Each session generates separate codes for each language:
followCodes: { nl: "ABCD", en: "EFGH"}Expiry
Section titled “Expiry”Follow codes expire after 24 hours and are regenerated automatically for active sessions.
Broadcasting
Section titled “Broadcasting”Server-Side
Section titled “Server-Side”The server broadcasts to all connected clients:
// Internal: Send to all clients in a sessionbroadcast(repoRoot, sessionId, 'state', { slideId: 'abc123', slideIndex: 5, updatedAt: Date.now()});Selective Broadcasting
Section titled “Selective Broadcasting”Some events go to specific clients or exclude the sender.
Performance
Section titled “Performance”Connection Limits
Section titled “Connection Limits”- Browser limit: ~6 SSE connections per domain
- Server handles thousands of concurrent connections
Bandwidth
Section titled “Bandwidth”SSE is efficient:
- Small event payloads
- HTTP/2 multiplexing supported
- Compression with gzip
Scalability
Section titled “Scalability”For horizontal scaling:
- Use Redis pub/sub for cross-instance broadcasts
- Sticky sessions or broadcast coordination needed
Troubleshooting
Section titled “Troubleshooting”Connection Drops
Section titled “Connection Drops”- Check proxy timeouts
- Verify heartbeat is reaching client
- Look for browser network throttling
Events Not Received
Section titled “Events Not Received”- Verify subscription to correct session
- Check authentication/permissions
- Monitor server logs for errors
High Latency
Section titled “High Latency”- Check server load
- Verify network path
- Consider geographic distribution
Security
Section titled “Security”Authentication
Section titled “Authentication”SSE endpoints validate:
- Session ownership
- User permissions
- Valid session tokens
Rate Limiting
Section titled “Rate Limiting”Connections are rate-limited:
- Max connections per IP
- Event frequency limits
- Prevents abuse