jonnifyelixir
F6 · Phoenix Framework / F6.07 · pubsub

F6 · the architecture · module 7

PubSub, channels & real-time

F6.06 made one LiveView live: its own socket, its own state, its own diffs. But a catalog has many viewers, and when one of them creates a course the others should see it without refreshing. That fan-out is Phoenix.PubSub — publish/subscribe between processes over a named topic. The shape is the OTP message passing the F5 engine already ran on: a process broadcasts a message, and every process subscribed to that topic receives it in its mailbox. The discipline that matters is where the broadcast comes from: the domain emits the event, in the context, right after a successful write — not the web layer. Each LiveView subscribes on its connected mount (the connected?/1 guard from F6.06.1) and handles the message in handle_info/2, the callback for process messages as opposed to handle_event/3 for browser clicks. Underneath LiveView sit channels, the raw real-time primitive for custom client protocols, and alongside them Presence, which tracks who is on a topic and stays correct across a whole cluster. One write becomes everyone’s live update, and the domain never learns the web exists.

Three dives: broadcasting domain events from the context, subscribing a LiveView and handling the message, and the channels and presence beneath and beside it — real-time on the same message passing as F5.

One write, many subscribers

PUBLISHER domain / context broadcast after a write TOPIC "catalog:lobby" Phoenix.PubSub SUBSCRIBERS LiveView handle_info/2 stale LiveView handle_info/2 stale LiveView handle_info/2 stale LiveView not joined —

idle — 3 LiveViews subscribed to "catalog:lobby", awaiting a broadcast
Press broadcast: the context publishes one event on the topic and every subscriber updates at once.

Three parts of real-time

Live updates are three moves, and this module takes each in turn. broadcast publishes a domain event to a topic. subscribe joins a topic so a LiveView receives those events. presence tracks who is on a topic, across nodes. Select a part.

Real-time · select a part

BROADCAST the context publishes an event to a topic — after a write F6.07.1 SUBSCRIBE a LiveView joins a topic — handle_info/2 receives events F6.07.2 PRESENCE track who is on a topic — synced across the cluster F6.07.3

part: broadcast

does: publish an event to a topic

PubSub is not a web feature bolted on — it is the BEAM’s native message passing exposed over a topic. The same broadcast reaches a LiveView, a background worker, or a process on another node, with no change to the caller.

One write, many clients

Trace a single create. A user submits the form; the LiveView calls the context; the context writes through the Repo and, on success, broadcasts {:course_created, course} on the "courses" topic. PubSub delivers that one message to every subscribed LiveView — including the author’s and everyone else’s — and each updates its assigns and pushes a diff to its own browser. One write, one broadcast, many live screens.

write → broadcast → every subscriber

context write create_course/1 · {:ok} broadcast PubSub topic "courses" LiveView A handle_info → diff LiveView B handle_info → diff LiveView C handle_info → diff 3 browsers, all live one broadcast reaches every subscriber — the domain emits it once, the web fans it out

The author’s own screen updates the same way as everyone else’s — through the broadcast, not a special case in the create handler. That uniformity is what keeps real-time code small: there is one path, and every client is on it.

Three deep dives

In order: broadcasting domain events from the context; subscribing a LiveView and handling the message; and the channels and presence that sit beneath and beside PubSub.

F6.07.1
Broadcasting engine events
Phoenix.PubSub, topics, and broadcasting from the context after a write — with a facade wrapper for the server name.
F6.07.2
Subscribing a LiveView
Subscribe on the connected mount, then handle_info/2 — process messages, not browser events — updating a stream.
F6.07.3
Channels & presence
The channel primitive beneath LiveView, and Presence for who is on a topic, synced across a cluster.

F5 emitted events

the engine recorded domain events to its EventStore as the source of truth.

F6.07 broadcasts them

the same kind of event, published on a topic, drives every live screen.

Start with broadcasting engine events, then subscribing a LiveView, then channels and presence. This module follows F6.06 — LiveView — and the next, F6.08, takes the whole app to production.

References

PubSub, channels, the handle_info/2 callback, and Presence.

Sources

Related in this course