Open-Source Wikis

/

Ruby on Rails

/

Packages

/

Action Cable

rails/rails

Action Cable

Active contributors: rafaelfranca, dhh, georgeclaghorn

Purpose

Action Cable integrates WebSockets with Rails. It provides a server (running inside the Rails process or standalone), a JavaScript client, a channel/connection abstraction modeled on controllers, and a pluggable broadcasting layer (Redis, Postgres, async, Solid Cable).

Source: actioncable/lib/action_cable/. ~4,200 lines of lib/ Ruby plus a JavaScript client in actioncable/app/javascript/.

Directory layout

actioncable/
├── app/
│   ├── assets/javascripts/
│   └── javascript/                       # Source for @rails/actioncable
├── lib/
│   └── action_cable/
│       ├── channel/                      # Channel base class + mixins
│       ├── connection/                   # Connection base + auth + identification
│       ├── server/                       # The pubsub server
│       ├── subscription_adapter/         # async, inline, postgresql, redis, test
│       ├── helpers/                      # ActionCable::Helpers (URL helpers)
│       ├── engine.rb
│       ├── remote_connections.rb
│       ├── test_case.rb
│       └── test_helper.rb
└── actioncable.gemspec

Key abstractions

Constant File Purpose
ActionCable::Channel::Base actioncable/lib/action_cable/channel/base.rb Subclass for each channel
ActionCable::Connection::Base actioncable/lib/action_cable/connection/base.rb One per WebSocket connection (auth, identification)
ActionCable::Server::Base actioncable/lib/action_cable/server/base.rb The pubsub server (often ActionCable.server)
ActionCable::SubscriptionAdapter::Base actioncable/lib/action_cable/subscription_adapter/base.rb Pluggable broadcast backends
ActionCable::RemoteConnections actioncable/lib/action_cable/remote_connections.rb Disconnect remote sockets across processes

How it works

graph TD
    subgraph Browser
        JS[ActionCable JS client]
    end
    subgraph Rails server
        WS[Cable Rack endpoint]
        Conn[Connection]
        Channel[Channel]
        Adapter[Subscription adapter]
    end
    subgraph Backend
        Bus[(Redis / Postgres / Solid Cable)]
    end
    JS <-->|WebSocket| WS
    WS --> Conn
    Conn --> Channel
    Channel <-->|broadcast| Adapter
    Adapter <--> Bus

A client connects to /cable (the path is configurable). ActionCable::Server accepts the WebSocket, instantiates a Connection, and delegates subscribe / unsubscribe / message calls to the appropriate Channel. When server-side code calls MyChannel.broadcast_to(record, payload), the message goes through the subscription adapter to every subscribed socket.

Connections

actioncable/lib/action_cable/connection/:

  • base.rb — connection lifecycle, message dispatch.
  • identification.rbidentified_by :current_user.
  • authorization.rbreject_unauthorized_connection.
  • subscriptions.rb — manages subscriptions per connection.
  • client_socket.rb — wraps the websocket-driver gem.
  • tagged_logger_proxy.rb — per-connection log tags.

Connections are typically defined in app/channels/application_cable/connection.rb.

Channels

actioncable/lib/action_cable/channel/:

  • base.rb — subscribe/unsubscribe lifecycle.
  • broadcasting.rbbroadcast_to, broadcasting_for.
  • callbacks.rbsubscribed, unsubscribed.
  • naming.rb — channel name conventions.
  • streams.rbstream_from, stream_for.
  • periodic_timers.rb — server-pushed heartbeats / periodic tasks.

Channels are typically defined in app/channels/<name>_channel.rb.

Subscription adapters

actioncable/lib/action_cable/subscription_adapter/:

  • async.rb — in-process Concurrent Ruby pub/sub. Default in development.
  • inline.rb — fully synchronous; useful only for tests.
  • redis.rb — Redis pub/sub for production.
  • postgresql.rb — uses LISTEN / NOTIFY.
  • test.rb — captures broadcasts in arrays.
  • subscriber_map.rb — shared bookkeeping.

Solid Cable (a separate gem, made default in Rails 8) provides a database-backed adapter that polls.

Server

ActionCable::Server::Base is the entry point. It's mounted as a Rack endpoint at /cable (configurable via config.action_cable.mount_path). The server runs inside your web server process by default; it can also be started standalone via bin/rails action_cable:server.

actioncable/lib/action_cable/server/:

  • base.rb
  • broadcasting.rb
  • configuration.rb
  • connections.rb — local connection registry.
  • worker.rb — thread-pool for channel callbacks (so they don't block the event loop).

JavaScript client

actioncable/app/javascript/action_cable/ contains the client library:

  • consumer.js — main entry point.
  • connection.js — WebSocket lifecycle and reconnect.
  • connection_monitor.js — heartbeat / detect dropped connections.
  • subscription.js, subscriptions.js, subscription_guarantor.js.

The package.json and rollup.config.js produce a UMD/ESM build published as @rails/actioncable on npm.

Testing

  • ActionCable::Channel::TestCase (actioncable/lib/action_cable/channel/test_case.rb) — subscribe(...), assert_broadcast_on(stream, data).
  • ActionCable::Connection::TestCaseconnect("/cable", cookies: ...).
  • ActionCable::TestHelperassert_broadcasts, perform_enqueued_subscriptions_for.

Integration points

  • Active Support: Notifications (broadcast.action_cable, transmit.action_cable).
  • Action Pack: mounted via the application's RouteSet.
  • Active Job: broadcasts can be enqueued asynchronously.

Entry points for modification

  • Adding a subscription adapter: subclass ActionCable::SubscriptionAdapter::Base and register via ActionCable::SubscriptionAdapter.discoverable_adapters. Tests under actioncable/test/subscription_adapter/<name>_test.rb.
  • Modifying the wire protocol: changes to connection/message_buffer.rb, subscriptions.rb, and the JS connection.js must stay in sync. The Rails 8 wire format simplification touched both sides.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Action Cable – Ruby on Rails wiki | Factory