# Action Cable y WebSockets en Rails: Guía Completa para Entrevistas Técnicas > Guia completa sobre Action Cable y WebSockets en Ruby on Rails para entrevistas tecnicas. Conexiones, canales, Solid Cable, Turbo Streams, escalabilidad con Redis y testing con ejemplos de codigo. - Published: 2026-05-07 - Updated: 2026-05-07 - Author: Anthony Fillion-Maillet - Tags: ruby on rails, action cable, websockets, tiempo real, solid cable, rails 8 - Reading time: 11 min --- La comunicación en tiempo real se ha convertido en un requisito fundamental para las aplicaciones web modernas. Desde chats en vivo hasta notificaciones instantáneas y dashboards actualizados automáticamente, los usuarios esperan experiencias fluidas sin necesidad de recargar la página. Ruby on Rails resuelve esta necesidad a través de Action Cable, un framework integrado que permite trabajar con WebSockets de manera elegante y siguiendo las convenciones del ecosistema Rails. Comprender Action Cable resulta esencial para cualquier desarrollador que aspire a construir aplicaciones robustas y prepararse adecuadamente para entrevistas técnicas donde la comunicación en tiempo real sea un tema relevante. > Action Cable integra WebSockets directamente en el stack de Rails, permitiendo escribir funcionalidades en tiempo real con el mismo estilo y productividad que caracteriza al framework. En Rails 8, Solid Cable ofrece una alternativa basada en base de datos que elimina la dependencia de Redis para muchos casos de uso. ## Fundamentos de WebSockets y Action Cable WebSockets establece un canal de comunicación bidireccional y persistente entre el cliente y el servidor. A diferencia de HTTP tradicional, donde cada solicitud requiere una nueva conexión, WebSockets mantiene una conexión abierta que permite el intercambio de mensajes en ambas direcciones con latencia mínima. Action Cable abstrae la complejidad de trabajar con WebSockets proporcionando una arquitectura basada en canales. Esta arquitectura se compone de tres elementos principales: la conexión, los canales y las suscripciones. La conexión representa el enlace WebSocket entre el cliente y el servidor, los canales encapsulan la lógica de negocio para diferentes funcionalidades, y las suscripciones permiten a los clientes recibir actualizaciones de canales específicos. El flujo de trabajo típico comienza cuando un usuario abre la aplicación y establece una conexión WebSocket. Una vez autenticada la conexión, el cliente puede suscribirse a uno o más canales. Cuando ocurre un evento relevante en el servidor, Action Cable transmite el mensaje a todos los suscriptores del canal correspondiente. ## Autenticación de Conexiones La seguridad constituye el primer aspecto crítico al implementar WebSockets. Cada conexión debe autenticarse para garantizar que solo usuarios legítimos puedan acceder a los canales. Action Cable proporciona un mecanismo de identificación que permite asociar cada conexión con un usuario específico. ```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 ``` El método `identified_by` declara un identificador que estará disponible en todos los canales. El método `connect` se ejecuta cuando se establece la conexión WebSocket y debe verificar la identidad del usuario. Si la verificación falla, `reject_unauthorized_connection` cierra la conexión inmediatamente. Este patrón de autenticación mediante cookies encriptadas funciona perfectamente cuando la aplicación Rails maneja tanto la autenticación web como las conexiones WebSocket. Para arquitecturas con autenticación basada en tokens JWT, es posible pasar el token como parámetro de conexión y validarlo en el método `find_verified_user`. ## Implementación de Canales Los canales representan el corazón de Action Cable. Cada canal encapsula la lógica para una funcionalidad específica en tiempo real, como un chat, notificaciones o actualizaciones de dashboard. La clase base `ApplicationCable::Channel` proporciona métodos para gestionar suscripciones, recibir datos y transmitir mensajes. ```ruby # app/channels/chat_channel.rb class ChatChannel < ApplicationCable::Channel def subscribed room = ChatRoom.find(params[:room_id]) 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 AppearanceTracker.mark_offline(current_user) end end ``` El método `subscribed` se invoca cuando un cliente intenta suscribirse al canal. Aquí se realiza la autorización verificando que el usuario tenga permiso para acceder al recurso solicitado. El método `stream_for` establece la transmisión de mensajes asociada a un objeto específico, en este caso la sala de chat. El método `receive` procesa los mensajes entrantes desde el cliente. Después de crear el mensaje en la base de datos, `broadcast_to` envía la información a todos los suscriptores del canal asociado con esa sala. El método `unsubscribed` permite ejecutar lógica de limpieza cuando el cliente se desconecta. ## Integración del Cliente JavaScript El lado del cliente requiere código JavaScript para establecer la conexión y manejar los mensajes. Rails proporciona un consumidor de Action Cable que simplifica la creación de suscripciones y el intercambio de datos. ```javascript // app/javascript/channels/chat_channel.js import consumer from "./consumer" const chatChannel = consumer.subscriptions.create( { channel: "ChatChannel", room_id: roomId }, { connected() { console.log("Connected to chat room", roomId) }, disconnected() { console.log("Disconnected from chat room") }, received(data) { const messageList = document.getElementById("messages") messageList.insertAdjacentHTML("beforeend", `
${data.user}: ${data.body}
` ) }, sendMessage(body) { this.perform("receive", { body: body }) } } ) ``` La función `subscriptions.create` recibe dos argumentos: un objeto con el nombre del canal y los parámetros necesarios, y un objeto con callbacks para diferentes eventos. El callback `connected` se ejecuta al establecer la conexión exitosamente, `disconnected` cuando se pierde la conexión, y `received` cada vez que llega un mensaje del servidor. El método `perform` permite invocar acciones definidas en el canal del servidor. En este ejemplo, `sendMessage` llama al método `receive` del `ChatChannel` pasando el cuerpo del mensaje como parámetro. ## Configuración con Solid Cable en Rails 8 Rails 8 introduce Solid Cable como adaptador predeterminado para Action Cable en desarrollo y producción. Solid Cable utiliza la base de datos como backend de pub/sub, eliminando la necesidad de configurar Redis para aplicaciones de escala moderada. ```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 ``` La configuración de producción especifica una base de datos dedicada para las operaciones de Action Cable. El parámetro `polling_interval` controla la frecuencia con que los workers verifican nuevos mensajes, mientras que `message_retention` determina cuánto tiempo se conservan los mensajes antes de ser eliminados automáticamente. Para utilizar una base de datos separada, es necesario configurar la conexión múltiple en el archivo de base de datos: ```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 ``` Esta separación de bases de datos permite escalar las operaciones de mensajería independientemente de la base de datos principal de la aplicación, optimizando el rendimiento bajo carga. ## Patrones de Broadcasting El broadcasting constituye el mecanismo principal para enviar mensajes desde el servidor hacia los clientes suscritos. Action Cable ofrece flexibilidad para transmitir desde diferentes contextos de la aplicación, incluyendo modelos, controladores y trabajos en segundo plano. ```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 ``` El broadcasting desde callbacks de modelo resulta útil para notificaciones inmediatas después de crear o actualizar registros. Para operaciones que requieren cálculos intensivos, como estadísticas de dashboard, delegar el trabajo a un job en segundo plano evita bloquear la respuesta del servidor y proporciona mayor resiliencia. La convención de nombrar canales con el formato `recurso_id` facilita la organización y permite a los clientes suscribirse a recursos específicos de manera predecible. ## Integración con Turbo Streams Hotwire y Turbo simplifican significativamente el trabajo con Action Cable mediante Turbo Streams. Esta integración permite actualizar fragmentos de HTML en tiempo real con mínimo código JavaScript. ```ruby # app/models/message.rb class Message < ApplicationRecord belongs_to :chat_room broadcasts_to :chat_room end # app/views/chat_rooms/show.html.erb <%= turbo_stream_from @chat_room %>
<%= render @chat_room.messages %>
``` El método `broadcasts_to` en el modelo configura automáticamente la transmisión de cambios cuando se crean, actualizan o eliminan mensajes. En la vista, `turbo_stream_from` establece la suscripción al canal correspondiente. Rails genera automáticamente las actualizaciones de DOM necesarias sin escribir JavaScript adicional. Esta aproximación declarativa reduce drásticamente la cantidad de código necesario para implementar funcionalidades en tiempo real, manteniendo la lógica de presentación en las vistas donde naturalmente pertenece. ## Configuración de Redis para Alta Escala Para aplicaciones con alto volumen de conexiones simultáneas y mensajes, Redis continúa siendo la opción recomendada como backend de pub/sub. Redis ofrece latencias extremadamente bajas y capacidad para manejar millones de operaciones por segundo. ```ruby # config/cable.yml — Redis adapter for high-scale production production: adapter: redis url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> channel_prefix: myapp_production ``` El parámetro `channel_prefix` resulta esencial cuando múltiples aplicaciones comparten la misma instancia de Redis, evitando colisiones de nombres de canales. La URL se obtiene de variables de entorno para mantener las credenciales fuera del código fuente. En entornos de producción robustos, se recomienda utilizar Redis Sentinel o Redis Cluster para alta disponibilidad. Servicios administrados como Amazon ElastiCache o Redis Cloud simplifican la operación y proporcionan características adicionales de monitoreo y failover automático. ## Testing de Canales Las pruebas automatizadas garantizan que los canales funcionen correctamente y manejen apropiadamente los casos de autorización. Rails proporciona helpers específicos para probar canales de Action Cable de manera aislada. ```ruby # test/channels/chat_channel_test.rb require "test_helper" class ChatChannelTest < ActionCable::Channel::TestCase test "subscribes to a valid room" do room = chat_rooms(:general) user = users(:alice) stub_connection current_user: user subscribe room_id: room.id assert subscription.confirmed? assert_has_stream_for room end test "rejects subscription for unauthorized user" do room = chat_rooms(:private) user = users(:outsider) stub_connection current_user: user subscribe room_id: room.id assert subscription.rejected? end test "broadcasts messages to room subscribers" do room = chat_rooms(:general) stub_connection current_user: users(:alice) subscribe room_id: room.id assert_broadcast_on(room, hash_including(body: "Hello")) do perform :receive, body: "Hello" end end end ``` El método `stub_connection` simula una conexión autenticada con el usuario especificado. `subscribe` intenta suscribirse al canal con los parámetros dados, permitiendo verificar si la suscripción fue confirmada o rechazada. La aserción `assert_has_stream_for` verifica que el canal esté transmitiendo correctamente para el objeto esperado. `assert_broadcast_on` confirma que al realizar una acción, el mensaje correspondiente se transmite a los suscriptores del canal. ## Consideraciones de Rendimiento y Escalabilidad El rendimiento de Action Cable depende de varios factores que deben considerarse durante el diseño de la aplicación. El número de conexiones simultáneas, la frecuencia de mensajes y el tamaño de los payloads impactan directamente en los recursos del servidor. Para optimizar el rendimiento, se recomienda limitar el tamaño de los mensajes transmitidos, incluyendo solo los datos necesarios para actualizar la interfaz. Utilizar trabajos en segundo plano para operaciones costosas evita bloquear los workers de Action Cable. Implementar debouncing en el cliente previene sobrecargar el servidor con mensajes frecuentes. El escalamiento horizontal requiere un backend de pub/sub compartido como Redis. Cuando múltiples instancias del servidor manejan conexiones WebSocket, Redis garantiza que los mensajes lleguen a todos los suscriptores independientemente del servidor al que estén conectados. ## Conclusión Action Cable proporciona una solución integrada y elegante para implementar comunicación en tiempo real en aplicaciones Rails. Desde la autenticación de conexiones hasta el testing de canales, el framework ofrece las herramientas necesarias para construir funcionalidades robustas siguiendo las convenciones del ecosistema Rails. Con la introducción de Solid Cable en Rails 8, la barrera de entrada se reduce significativamente al eliminar dependencias externas para casos de uso comunes. Dominar estos conceptos resulta fundamental para desarrolladores que buscan destacar en entrevistas técnicas y construir aplicaciones modernas que cumplan con las expectativas de los usuarios actuales. [Practicar preguntas de entrevista sobre ActionCable y WebSockets](/es/technologies/ruby-on-rails/interview-questions/action-cable-websockets) --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/es/blog/ruby-on-rails/action-cable-websockets-complete-guide