# Action Cable e WebSocket in Rails: Guida Completa per Colloqui Tecnici 2026 > Approfondimento su Action Cable per colloqui Rails. Connessioni, channel, Solid Cable, Turbo Streams, scalabilità con Redis e pattern di test con esempi di codice. - Published: 2026-05-07 - Updated: 2026-05-07 - Author: Anthony Fillion-Maillet - Tags: ruby-on-rails, action-cable, websockets, real-time, interviews - Reading time: 9 min --- Action Cable integra il supporto WebSocket direttamente nel framework Rails, abilitando funzionalità in tempo reale come chat, notifiche e dashboard live senza dipendenze esterne. Per i colloqui tecnici del 2026, la padronanza degli aspetti interni di Action Cable — dal ciclo di vita delle connessioni alla scalabilità in produzione — rappresenta un vantaggio decisivo rispetto agli altri candidati. > **Concetto Chiave per i Colloqui** > > Action Cable integra i WebSocket nel framework Rails utilizzando le stesse convenzioni impiegate per controller e model. Rails 8 introduce Solid Cable, un adapter basato su database che elimina la dipendenza da Redis per il messaging pub/sub. ## Fondamenti del Protocollo WebSocket nel Contesto Rails Il protocollo WebSocket (RFC 6455) stabilisce un canale di comunicazione persistente e full-duplex su una singola connessione TCP. A differenza dei cicli request-response HTTP, i WebSocket mantengono una connessione aperta in cui sia il client che il server possono inviare messaggi in qualsiasi momento. Action Cable racchiude questo protocollo in un'astrazione compatibile con Rails. Il server gestisce gli upgrade WebSocket su `/cable`, amministra l'autenticazione delle connessioni e instrada i messaggi attraverso i channel. La libreria JavaScript lato client crea e gestisce le subscription automaticamente. Una tipica richiesta HTTP si completa in millisecondi e chiude la connessione. Una connessione WebSocket rimane aperta per minuti, ore o l'intera durata della sessione. Questa differenza fondamentale guida ogni decisione architetturale in Action Cable. ## Architettura di Action Cable: Connection, Channel e Subscription Action Cable segue un'architettura stratificata con tre astrazioni principali: le connection gestiscono l'autenticazione, i channel incapsulano la logica di business, e le subscription collegano i consumer a channel specifici. ```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 # Cookies are available in WebSocket handshake if verified_user = User.find_by(id: cookies.encrypted[:user_id]) verified_user else reject_unauthorized_connection end end end end ``` La classe connection viene eseguita una sola volta per ogni handshake WebSocket. L'autenticazione avviene qui — non nei singoli channel. La dichiarazione `identified_by` registra l'identità dell'utente, rendendola disponibile in tutte le subscription dei channel su quella connessione. ```ruby # app/channels/chat_channel.rb class ChatChannel < ApplicationCable::Channel def subscribed room = ChatRoom.find(params[:room_id]) # Authorization: verify user belongs to this room if room.members.include?(current_user) stream_for room else reject end end def receive(data) message = ChatMessage.create!( room_id: params[:room_id], user: current_user, body: data["body"] ) ChatChannel.broadcast_to( message.room, { id: message.id, body: message.body, user: current_user.name } ) end def unsubscribed # Cleanup: mark user as offline AppearanceTracker.mark_offline(current_user) end end ``` I channel definiscono tre callback del ciclo di vita: `subscribed`, `receive` e `unsubscribed`. Il metodo `stream_for` associa la subscription a una specifica istanza del model, creando uno stream con namespace. Il broadcasting su quello stream consegna i messaggi a ogni subscriber connesso. ## Subscription Lato Client con JavaScript Il consumer lato client si connette al server Action Cable e gestisce le subscription. Ogni subscription corrisponde a un channel lato server. ```javascript // app/javascript/channels/chat_channel.js import consumer from "./consumer" const chatChannel = consumer.subscriptions.create( { channel: "ChatChannel", room_id: roomId }, { connected() { // Called when the subscription is ready console.log("Connected to chat room", roomId) }, disconnected() { // Called when the subscription is closed console.log("Disconnected from chat room") }, received(data) { // Called when data is broadcast to the channel const messageList = document.getElementById("messages") messageList.insertAdjacentHTML("beforeend", `
` ) }, sendMessage(body) { // Calls ChatChannel#receive on the server this.perform("receive", { body: body }) } } ) ``` Il callback `received` si attiva ogni volta che il server trasmette allo stream sottoscritto. Il metodo `perform` invia dati dal client al server, invocando il metodo corrispondente del channel. ## Solid Cable in Rails 8: Pub/Sub Basato su Database Rails 8 introduce Solid Cable come parte della "Solid Trifecta" insieme a Solid Queue e Solid Cache. Solid Cable sostituisce Redis come backend pub/sub memorizzando i messaggi in una tabella del database. ```yaml # config/cable.yml (Rails 8 default) development: adapter: solid_cable production: adapter: solid_cable connects_to: database: writing: cable polling_interval: 0.1.seconds message_retention: 1.day ``` Solid Cable funziona scrivendo ogni messaggio broadcast in una tabella del database e interrogando periodicamente per nuovi messaggi a un intervallo configurabile. L'intervallo di polling predefinito di 100ms fornisce una consegna quasi in tempo reale per la maggior parte delle applicazioni. Il compromesso è chiaro: Solid Cable elimina una dipendenza infrastrutturale (Redis) al costo di una latenza leggermente superiore e maggiore carico sul database. Per le applicazioni che già utilizzano PostgreSQL o MySQL, questo compromesso è spesso sensato. Per il broadcasting ad alta frequenza (migliaia di messaggi al secondo), Redis rimane la scelta migliore. ```ruby # config/database.yml (Rails 8 multi-database) production: primary: <<: *default database: myapp_production cable: <<: *default database: myapp_cable_production migrations_paths: db/cable_migrate ``` Solid Cable utilizza un database dedicato per evitare contesa con il database primario. Questa separazione impedisce al polling dei messaggi di interferire con le query dell'applicazione. ## Pattern di Broadcasting e Trigger Lato Server Il broadcasting da model, job e controller copre i tre pattern più comuni nelle applicazioni Rails in produzione. ```ruby # Broadcasting from a model callback class Notification < ApplicationRecord belongs_to :user after_create_commit :broadcast_to_user private def broadcast_to_user ActionCable.server.broadcast( "notifications_#{user_id}", { id: id, title: title, read: false } ) end end # Broadcasting from a background job class DashboardUpdateJob < ApplicationJob queue_as :default def perform(dashboard_id) dashboard = Dashboard.find(dashboard_id) stats = dashboard.compute_stats ActionCable.server.broadcast( "dashboard_#{dashboard_id}", { stats: stats, updated_at: Time.current.iso8601 } ) end end ``` I callback dei model sono adatti per notifiche semplici attivate da modifiche ai record. I background job gestiscono calcoli più pesanti — come statistiche dashboard o aggregazioni di dati — senza bloccare il ciclo di richiesta. Il broadcast stesso è sempre leggero: serializza il payload e lo pubblica attraverso l'adapter. ## Turbo Streams e Integrazione con Action Cable Rails 8 con Hotwire utilizza Action Cable come livello di trasporto per i Turbo Streams, abilitando aggiornamenti DOM in tempo reale senza scrivere JavaScript personalizzato. ```ruby # app/models/message.rb class Message < ApplicationRecord belongs_to :chat_room # Automatically broadcasts append to subscribers broadcasts_to :chat_room end # app/views/chat_rooms/show.html.erb <%= turbo_stream_from @chat_room %>