action-cable-realtime
This skill should be used when the user asks about Action Cable, WebSockets, real-time features, channels, broadcasting, subscriptions, chat applications, live notifications, presence indicators, collaborative editing, server push, pub/sub patterns, Solid Cable, or streaming updates. Also use when discussing real-time architecture, WebSocket deployment, or alternatives like polling and Server-Sent Events. Examples:
Best use case
action-cable-realtime is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
This skill should be used when the user asks about Action Cable, WebSockets, real-time features, channels, broadcasting, subscriptions, chat applications, live notifications, presence indicators, collaborative editing, server push, pub/sub patterns, Solid Cable, or streaming updates. Also use when discussing real-time architecture, WebSocket deployment, or alternatives like polling and Server-Sent Events. Examples:
Teams using action-cable-realtime should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/action-cable-realtime/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How action-cable-realtime Compares
| Feature / Agent | action-cable-realtime | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
This skill should be used when the user asks about Action Cable, WebSockets, real-time features, channels, broadcasting, subscriptions, chat applications, live notifications, presence indicators, collaborative editing, server push, pub/sub patterns, Solid Cable, or streaming updates. Also use when discussing real-time architecture, WebSocket deployment, or alternatives like polling and Server-Sent Events. Examples:
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Action Cable & Real-Time: WebSockets in Rails
## Overview
Action Cable integrates WebSockets with Rails, enabling real-time features like chat, notifications, and live updates. It provides both server-side Ruby and client-side JavaScript frameworks that work together seamlessly.
**Action Cable enables:**
- Real-time chat and messaging
- Live notifications
- Presence indicators (who's online)
- Collaborative editing
- Live dashboard updates
- Real-time feeds
Rails 8 introduces **Solid Cable**, which replaces Redis with database-backed pub/sub, simplifying deployment.
## Core Concepts
### WebSockets vs HTTP
**HTTP (Request-Response):**
```
Client → Request → Server
Client ← Response ← Server
[Connection closes]
```
**WebSocket (Persistent Connection):**
```
Client ↔ Persistent Connection ↔ Server
[Messages flow both directions]
[Connection stays open]
```
Benefits:
- Bi-directional communication
- Low latency (no connection overhead)
- Server can push to clients
- Efficient for real-time features
### Action Cable Architecture
```
Browser (Consumer) → WebSocket → Connection → Channels → Broadcasters
```
**Connection**: WebSocket connection (one per browser tab)
**Channel**: Logical grouping (like a controller)
**Subscription**: Consumer subscribed to a channel
**Broadcasting**: Message sent to all channel subscribers
## Channels
Channels are like controllers for WebSockets.
### Creating a Channel
```bash
rails generate channel Chat
```
Generates:
```ruby
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
# Called when consumer subscribes
stream_from "chat_#{params[:room_id]}"
end
def unsubscribed
# Called when consumer unsubscribes (cleanup)
end
def speak(data)
# Called when consumer sends message
Message.create!(
content: data['message'],
user: current_user,
room_id: params[:room_id]
)
end
end
```
```javascript
// app/javascript/channels/chat_channel.js
import consumer from "./consumer"
consumer.subscriptions.create(
{ channel: "ChatChannel", room_id: 123 },
{
connected() {
console.log("Connected to chat")
},
disconnected() {
console.log("Disconnected from chat")
},
received(data) {
// Handle broadcasted message
const messagesContainer = document.getElementById("messages")
messagesContainer.insertAdjacentHTML("beforeend", data.html)
},
speak(message) {
this.perform("speak", { message: message })
}
}
)
```
### Streaming
Subscribe to broadcasts:
```ruby
class ChatChannel < ApplicationCable::Channel
def subscribed
# Stream from named channel
stream_from "chat_room_#{params[:room_id]}"
# Stream for current user only
stream_for current_user
# Stop streaming
stop_all_streams
end
end
```
### Channel Callbacks
Channels support lifecycle callbacks and exception handling:
```ruby
class ChatChannel < ApplicationCable::Channel
before_subscribe :verify_access
after_subscribe :log_subscription
rescue_from UnauthorizedError, with: :handle_unauthorized
def subscribed
stream_from "chat_#{params[:room_id]}"
end
private
def verify_access
reject unless current_user.can_access?(params[:room_id])
end
def log_subscription
Rails.logger.info "User #{current_user.id} subscribed to chat"
end
def handle_unauthorized(exception)
# Handle error, optionally broadcast error message
transmit(error: "Unauthorized access")
end
end
```
Available callbacks: `before_subscribe`, `after_subscribe`, `before_unsubscribe`, `after_unsubscribe`.
## Broadcasting
Send messages to channel subscribers:
### From Models
```ruby
class Message < ApplicationRecord
belongs_to :room
belongs_to :user
after_create_commit :broadcast_message
private
def broadcast_message
ActionCable.server.broadcast(
"chat_room_#{room_id}",
{
html: ApplicationController.render(
partial: 'messages/message',
locals: { message: self }
),
user: user.name
}
)
end
end
```
### From Controllers
```ruby
class MessagesController < ApplicationController
def create
@message = Message.new(message_params)
if @message.save
# Broadcast happens in model callback
head :ok
else
render json: { errors: @message.errors }, status: :unprocessable_entity
end
end
end
```
### From Jobs
```ruby
class NotificationBroadcastJob < ApplicationJob
queue_as :default
def perform(notification)
ActionCable.server.broadcast(
"notifications_#{notification.user_id}",
{ html: render_notification(notification) }
)
end
private
def render_notification(notification)
ApplicationController.render(
partial: 'notifications/notification',
locals: { notification: notification }
)
end
end
```
## Authentication
Authenticate WebSocket connections:
```ruby
# app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
end
```
Now `current_user` is available in all channels.
## Rails 8: Solid Cable
Solid Cable replaces Redis with database-backed pub/sub.
### Configuration
```yaml
# config/cable.yml
production:
adapter: solid_cable
polling_interval: 0.1 # 100ms
message_retention: 1.day
```
```ruby
# No Redis needed!
# Solid Cable stores messages in database
# Polls for new messages every 100ms
```
### Migration
```bash
rails solid_cable:install
rails db:migrate
```
Creates `solid_cable_messages` table.
### Trade-offs
**Solid Cable:**
- Simpler deployment (no Redis)
- One database to manage
- ~100-150ms latency
- Sufficient for chat, notifications, updates
**Redis:**
- Lower latency (<50ms)
- Higher throughput
- Better for millions of connections
For most apps, Solid Cable is simpler and sufficient.
See `references/solid-cable.md` for details.
## Common Patterns
### Chat Application
```ruby
# Channel
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_#{params[:room_id]}"
end
def speak(data)
Message.create!(
room_id: params[:room_id],
user: current_user,
content: data['message']
)
end
end
# Model
class Message < ApplicationRecord
after_create_commit -> {
broadcast_append_to "chat_#{room_id}",
target: "messages",
partial: "messages/message",
locals: { message: self }
}
end
```
### Live Notifications
```ruby
class NotificationChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
end
# Broadcast to specific user
NotificationChannel.broadcast_to(user, {
html: render_notification(notification)
})
```
### Presence (Who's Online)
```ruby
class AppearanceChannel < ApplicationCable::Channel
def subscribed
stream_from "appearances"
broadcast_appearance("online")
end
def unsubscribed
broadcast_appearance("offline")
end
def appear
broadcast_appearance("online")
end
def away
broadcast_appearance("away")
end
private
def broadcast_appearance(status)
ActionCable.server.broadcast("appearances", {
user_id: current_user.id,
username: current_user.name,
status: status
})
end
end
```
See `references/action-cable-patterns.md` for more examples.
## Testing
### Channel Tests
```ruby
require "test_helper"
class ChatChannelTest < ActionCable::Channel::TestCase
test "subscribes to stream" do
subscribe room_id: 42
assert subscription.confirmed?
assert_has_stream "chat_42"
end
test "receives broadcasts" do
subscribe room_id: 42
perform :speak, message: "Hello!"
assert_broadcast_on("chat_42", message: "Hello!")
end
end
```
### Integration Tests
```ruby
test "broadcasts message to chat" do
room = rooms(:general)
assert_broadcasts("chat_#{room.id}", 1) do
Message.create!(room: room, user: users(:alice), content: "Hello!")
end
end
```
## Deployment Considerations
### Standalone Server
For high-traffic apps, run Action Cable on separate servers:
```ruby
# config/cable.yml
production:
adapter: solid_cable
url: wss://cable.example.com
```
### Scaling
Action Cable scales horizontally:
- Multiple app servers
- Shared pub/sub (Solid Cable database or Redis)
- Load balancer with WebSocket support
### Monitoring
Track connection count, message throughput, latency, and errors.
## Alternatives to Action Cable
### Server-Sent Events (SSE)
One-way server → client:
```ruby
def stream
response.headers['Content-Type'] = 'text/event-stream'
response.headers['Cache-Control'] = 'no-cache'
sse = SSE.new(response.stream)
sse.write({ message: "Hello" })
ensure
sse.close
end
```
**Use when:** Only server → client needed (notifications, live feeds)
### Polling
Regular HTTP requests:
```javascript
setInterval(() => {
fetch('/api/notifications/latest')
.then(r => r.json())
.then(data => updateUI(data))
}, 5000)
```
**Use when:** Simple updates, low frequency, broad browser support needed
## Further Reading
For deeper exploration:
- **`references/action-cable-patterns.md`**: Chat, notifications, presence patterns
- **`references/solid-cable.md`**: Database-backed pub/sub in Rails 8
For code examples (in `examples/`):
- **`chat-channel.rb`**: Real-time chat with typing indicators
- **`notifications-channel.rb`**: User-specific push notifications
- **`presence-channel.rb`**: Online status tracking
- **`dashboard-channel.rb`**: Admin dashboard with live stats
- **`multi-room-chat.rb`**: Multiple rooms with private messages
- **`collaborative-editing.rb`**: Document editing with cursors
- **`live-feed.rb`**: Real-time feed updates
## Summary
Action Cable provides:
- **WebSocket integration** with Rails
- **Channels** for logical grouping
- **Broadcasting** to connected clients
- **Authentication** via connection identification
- **Solid Cable** for database-backed pub/sub (Rails 8)
- **Turbo Streams** integration for HTML updates
Master Action Cable and you'll build real-time features that feel magical.Related Skills
add-reaction
Slack メッセージにリアクションを追加する。「リアクション追加」「リアクションつけて」「👍つけて」「絵文字で反応」「リアクションで返信」「いいねして」「リアクション送って」などで起動。User Token があればユーザーとしてリアクション、なければ Bot としてリアクション。
actions-pattern
Garante que novas Actions sigam o padrão de classes actions reutilizáveis do Easy Budget.
actionbook
This skill should be used when the user needs to automate multi-step website tasks. Activates for browser automation, web scraping, UI testing, or building AI agents. Provides complete action manuals with step-by-step instructions and verified selectors.
actionable-review-format-standards
Standardized output format for code reviews with severity labels, file:line references, and fix code snippets. Use when generating review reports that need consistent, actionable feedback structure.
action-policy-coder
Use proactively for authorization with ActionPolicy. Creates policies, scopes, and integrates with GraphQL/ActionCable. Preferred over Pundit for composable, cacheable authorization.
Action Pattern Conventions
This skill should be used when the user asks about "Laravel action pattern", "action class naming", "how to structure actions", "React component patterns", "Node.js service structure", "framework-specific conventions", or discusses creating reusable, focused classes following action pattern conventions in Laravel, Symfony, React, Vue, or Node.js projects.
action-mapping-designer
This skill should be used when ensuring training focuses on performance outcomes and business impact. Use this skill to identify essential content, design performance-focused activities, create job aids, and eliminate unnecessary training.
action-item-organizer
Systematic framework for extracting actionable items from documents and organizing them into prioritized, trackable checklists. Use when converting reports, meeting notes, audits, or any document with embedded action items into structured TODO lists.
action-creator
Creates user-specific one-click action templates that execute email operations when clicked in the chat interface. Use when user wants reusable actions for their specific workflows (send payment reminder to ACME Corp, forward bugs to engineering, archive old newsletters from specific sources).
Action Cable & WebSocket Patterns
Real-time WebSocket features with Action Cable in Rails. Use when: (1) Building real-time chat, (2) Live notifications/presence, (3) Broadcasting model updates, (4) WebSocket authorization. Trigger keywords: Action Cable, WebSocket, real-time, channels, broadcasting, stream, subscriptions, presence, cable
action-builder-skill
Use when creating or refactoring Nango integration actions to be thin API wrappers - provides patterns for minimal transformation logic, direct proxy calls, and standardized structure
acc-create-action
Generates ADR Action classes for PHP 8.5. Creates single-responsibility HTTP endpoint handlers with PSR-7 support. Includes unit tests.