Phoenix Channels & WebSockets
Relevant source files
The following files were used as context for generating this wiki page:
Phoenix Channels and WebSockets serve as the primary realtime transport layer for the LiveCanvas platform. While GraphQL handles durable reads and writes, the WebSocket infrastructure is dedicated to low-latency, transient data exchanges and state synchronization required for live interactions. This system facilitates features such as live chat, presence tracking, countdown broadcasts, and session state transitions.
The implementation relies on Phoenix's built-in PubSub and Presence modules to coordinate distributed state across multiple Kubernetes pods. This ensures that even in a multi-node environment, participants in a live session receive consistent updates regarding join/leave events and chat messages without requiring a shared external cache like Redis.
Sources: ARCHITECTURE.md:27-30, ARCHITECTURE.md:126-133
Realtime Architecture and Coordination
The architecture follows a modular monolith approach where each pod runs the same Elixir release, capable of serving WebSocket connections alongside GraphQL and REST requests. Coordination is strictly ephemeral, utilizing OTP processes to manage runtime entities.
Distributed State Management
Distributed coordination is handled through two core Elixir/Phoenix components:
- Phoenix PubSub: Manages the broadcasting of messages (e.g., chat, session updates) across the cluster.
- Phoenix Presence: Tracks active participant state and exposes minimum client-visible information to ensure privacy and performance.
Sources: ARCHITECTURE.md:37-41, ARCHITECTURE.md:129-130
Connection Lifecycle
The following diagram illustrates the flow from a client establishing a WebSocket connection to joining a specific live session topic.
The diagram shows the authentication and authorization handshake required before a user can participate in realtime events.
Sources: ARCHITECTURE.md:162-168, assets/js/app.js:28-32
Channel Topics and Use Cases
The backend utilizes Phoenix Channels for specific high-velocity or state-sensitive features that are ill-suited for traditional HTTP request-response cycles.
| Feature | Topic Pattern | Scope |
|---|---|---|
| Live Chat | chat:session_id | Realtime messaging, moderation events, and system notifications. |
| Presence | presence:session_id | Tracking active viewers and hosts in a live stream. |
| Session State | live:session_id | Countdown broadcasts, start/end intents, and status transitions. |
| User Notifications | user:user_id | Specific notifications for join/leave events or direct updates. |
Sources: ARCHITECTURE.md:126-133, ARCHITECTURE.md:143-149
Live Session Lifecycle Integration
WebSocket events are critical to the Live context's management of session state. When a host initiates a session, the backend transitions the live_sessions record through several states, broadcasting updates via Channels at each step.
Session State Transitions
This flow describes how transient WebSocket broadcasts mirror the durable state changes in Postgres.
Sources: ARCHITECTURE.md:143-152, mobile/schema.graphql:595-599
Key Realtime Mutations
While state is broadcast over Channels, the initial intents are often triggered via GraphQL mutations:
startLiveSession: Creates the record and initiates the supervised session process.goLiveSession: Transitions state toliveonce media negotiation succeeds.joinLiveSession/leaveLiveSession: Triggers presence updates and authorization checks.
Sources: mobile/schema.graphql:46-51, ARCHITECTURE.md:143-150
Security and Authorization
Security for WebSockets is applied at two levels: connection and join.
- Connection Level: The initial WebSocket connection must establish a
current_useridentity via token-based authentication. - Join Level: Every channel join request is validated against the
Socialcontext to enforce relationship-based access rules. This includes:- Verifying if the account is public or private.
- Checking if the viewer has a valid follow relationship.
- Ensuring the viewer is not blocked by the host.
Sources: ARCHITECTURE.md:162-171, AGENTS.md:13-15
Client-Side Implementation (Web)
In the web client, the LiveSocket is established using a CSRF token for security. The application uses phoenix_live_view for interactive elements and standard phoenix sockets for custom channel logic.
// assets/js/app.js:28-32
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
const liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: {_csrf_token: csrfToken},
hooks: {...colocatedHooks},
})
Sources: assets/js/app.js:28-32
Summary
Phoenix Channels provide the essential realtime fabric for LiveCanvas, handling all transient state synchronization that does not require Postgres persistence. By leveraging Elixir's OTP and Phoenix's coordination tools (PubSub and Presence), the system maintains high performance and scalability across a modular-monolith architecture without the need for external state stores like Redis. All realtime interactions are strictly governed by the same authorization and privacy policies defined in the core Social and Accounts contexts.