ActionCable: custom channels
This course studies ActionCable channels through the one channel this app runs: Turbo::StreamsChannel, from the turbo-rails gem. It explains why the app has no app/channels directory and no connection identity. It also shows how signed stream names authorize subscriptions through ActiveSupport::MessageVerifier. A throwaway channel tested with ActionCable::Channel::TestCase demonstrates stream_from and stream_for. The lessons then follow the subscription lifecycle through subscribed, reject and unsubscribed. They close by comparing a Turbo Stream refresh signal with custom JSON data sent by broadcast_to.
What you'll learn
- ✓How Turbo::StreamsChannel subscribes, verifies stream names and rejects
- ✓What identified_by does and what an empty identifiers set means
- ✓How signed stream names authorize subscriptions without user identity
- ✓How stream_from and stream_for register streams, tested with ActionCable::Channel::TestCase
- ✓How subscribe_to_channel, reject and stop_all_streams shape the channel lifecycle
- ✓When to broadcast a refresh signal and when to send a JSON data payload
This app's one real channel isn't custom
app/channels/ doesn't exist in this app. It isn't empty; find app/channels finds nothing at all. Yet the roadmap page refreshes live when an admin reorders a course, over a WebSocket, through an ActionCable channel. This lesson is about the channel that does it, and the app didn't write it.
Read the full lesson free →Curriculum
7 lessonsThis app's one real channel isn't custom
The app has no app/channels directory, and its one live channel is Turbo::StreamsChannel from turbo-rails.
Connections have no identity here
What identified_by does, and why this app's empty identifiers set gives every connection the same identifier.
Signed stream names: the real authorization this app has
How Turbo signs stream names with a MessageVerifier, and how a tampered token returns nil and triggers reject.
stream_from and stream_for, verified live
A throwaway channel tested with ActionCable::Channel::TestCase shows stream_from working and stream_for computing names from models.
subscribed, reject, unsubscribed: the lifecycle
How subscribe_to_channel calls subscribed and checks the reject flag afterwards, and how stop_all_streams cleans up on unsubscribe.
Broadcasting custom data vs Turbo Stream HTML
Compares the app's 70-byte Turbo Stream refresh signal with custom JSON data sent through broadcast_to.
Putting it together: a channel this app has never needed
A review of every mechanism covered, plus a BroadcastHub challenge that models streams and broadcasts in plain Ruby.