๐Ÿ“ก

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: async adapter (default, single process)

  • Production: must use redis or solid_cable adapter

  • Rails 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::Connection with cookies.encrypted[:user_id]

  • config.action_cable.allowed_request_origins โ€” required domain allowlist

  • Production: must use wss:// (TLS)

4. Connection management & memory

  • Each WebSocket connection occupies server memory persistently

  • Clean up resources in Channel unsubscribed callback

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::TestCase for Channel unit tests

  • assert_broadcast_on / assert_has_stream for broadcast verification

  • Integration tests: Capybara + JS driver (System Test) for WebSocket behavior

Key Points

1

rails generate channel Chat โ†’ create Channel class

2

Subscribe to channel with stream_from in subscribed

3

Broadcast messages with ActionCable.server.broadcast

4

Client subscribes with consumer.subscriptions.create

5

Process received data in received callback

6

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

Use Cases

Real-time chat Notification system Real-time dashboard Collaborative editing Live feed Real-time speech-to-text (STT โ€” WebSocket proxy) Live streaming comments/reactions