Action Cable
Rails built-in WebSocket โ real-time features
Action Cable is a WebSocket framework built into Rails that enables real-time serverโclient communication.
Server (Channel): Subscribe to channels in ChatChannel with stream_from "chat_room_1" in the subscribed method, and broadcast received data with ActionCable.server.broadcast.
Client (JavaScript): Subscribe to channels with consumer.subscriptions.create, and reflect received data in the DOM via the received callback.
Combined with Turbo Stream, real-time DOM updates are possible without JavaScript. Use Turbo::StreamsChannel.broadcast_append_to to add/modify/delete DOM elements directly from the server.
WebSocket Use Case: Real-time Speech-to-Text (STT)
WebSocket is key for real-time speech recognition (STT). Services like Deepgram and Azure Speech open a WebSocket connection and stream audio in 100-200ms chunks, returning interim and final results in real-time.
REST API approach (Groq Whisper): Cut recordings into 4-second segments sent via HTTP POST โ 4-5 second delay, context loss
WebSocket approach (Deepgram/Azure): Continuous audio chunk streaming โ 0.3-1 second delay, context preserved
Notes for WebSocket in Rails
1. Production adapter required
Development:
asyncadapter (default, single process)Production: must use
redisorsolid_cableadapterRails 8: Solid Cable (DB-based) available โ production without Redis
2. Nginx/Reverse proxy configuration
- WebSocket requires HTTP Upgrade handshake โ separate Nginx config required
3. Authentication & Security
Authenticate in
ApplicationCable::Connectionwithcookies.encrypted[:user_id]config.action_cable.allowed_request_originsโ required domain allowlistProduction: must use
wss://(TLS)
4. Connection management & memory
Each WebSocket connection occupies server memory persistently
Clean up resources in Channel
unsubscribedcallback
5. Horizontal scaling
Multi-server: Redis Pub/Sub for cross-server message sync
Load balancer: Sticky Session required
Large scale: Consider AnyCable โ Go/Rust based, 10x performance vs Ruby, Action Cable API compatible
6. Testing
ActionCable::Channel::TestCasefor Channel unit testsassert_broadcast_on/assert_has_streamfor broadcast verificationIntegration tests: Capybara + JS driver (System Test) for WebSocket behavior
Key Points
rails generate channel Chat โ create Channel class
Subscribe to channel with stream_from in subscribed
Broadcast messages with ActionCable.server.broadcast
Client subscribes with consumer.subscriptions.create
Process received data in received callback
Combined with Turbo Stream: auto DOM update via broadcast_append_to
Pros
- ✓ Built into Rails โ no extra installation
- ✓ Perfect integration with Turbo Stream
- ✓ Structural with Channel pattern
- ✓ Auto authentication integration (current_user)
- ✓ Rails 8: Production-ready without Redis via Solid Cable
Cons
- ✗ WebSocket connection maintenance cost (memory/connections)
- ✗ Redis adapter required (production, Rails 7 and below)
- ✗ Sticky Sessions or AnyCable needed for horizontal scaling
- ✗ Difficult debugging (async + network)
- ✗ Nginx WebSocket Upgrade configuration required