# Action Cable en WebSockets in Rails: Complete Gids voor Technische Sollicitatiegesprekken 2026 > Diepgaande behandeling van Action Cable voor Rails-interviews. Verbindingen, channels, Solid Cable, Turbo Streams, schaling met Redis en testpatronen met codevoorbeelden. - 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 brengt WebSocket-ondersteuning rechtstreeks naar het Rails-framework, waardoor realtime functionaliteiten zoals chat, notificaties en live dashboards mogelijk worden zonder externe afhankelijkheden. Voor technische sollicitatiegesprekken in 2026 is het begrijpen van de interne werking van Action Cable — van de levenscyclus van verbindingen tot productie-schaling — een doorslaggevend voordeel ten opzichte van andere kandidaten. > **Kernpunt voor Sollicitaties** > > Action Cable integreert WebSockets in het Rails-framework met dezelfde conventies die worden gebruikt voor controllers en models. Rails 8 introduceert Solid Cable, een database-gebaseerde adapter die de Redis-afhankelijkheid voor pub/sub-messaging elimineert. ## Basisprincipes van het WebSocket-Protocol in de Rails-Context Het WebSocket-protocol (RFC 6455) creëert een persistent, full-duplex communicatiekanaal over een enkele TCP-verbinding. In tegenstelling tot HTTP request-response-cycli houden WebSockets een open verbinding in stand waarbij zowel client als server op elk moment berichten kunnen versturen. Action Cable verpakt dit protocol in een Rails-compatibele abstractie. De server verwerkt WebSocket-upgrades op `/cable`, beheert verbindingsauthenticatie en routeert berichten via channels. De JavaScript-bibliotheek aan de clientzijde maakt en beheert subscriptions automatisch. Een typisch HTTP-verzoek wordt in milliseconden afgehandeld en de verbinding wordt gesloten. Een WebSocket-verbinding blijft daarentegen minuten, uren of de gehele sessieduur open. Dit fundamentele verschil bepaalt elke architectuurbeslissing in Action Cable. ## Action Cable-Architectuur: Connections, Channels en Subscriptions Action Cable volgt een gelaagde architectuur met drie kernabstracties: connections verzorgen authenticatie, channels bevatten de bedrijfslogica, en subscriptions koppelen consumers aan specifieke channels. ```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 ``` De connection-klasse wordt eenmalig uitgevoerd per WebSocket-handshake. Authenticatie vindt hier plaats — niet in individuele channels. De `identified_by`-declaratie registreert de gebruikersidentiteit en maakt deze beschikbaar in alle channel-subscriptions op die verbinding. ```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 ``` Channels definiëren drie levenscyclus-callbacks: `subscribed`, `receive` en `unsubscribed`. De methode `stream_for` bindt de subscription aan een specifieke modelinstantie en creëert een stream met namespace. Broadcasting naar die stream levert berichten af aan elke verbonden subscriber. ## Clientzijdige Subscriptions met JavaScript De clientzijdige consumer maakt verbinding met de Action Cable-server en beheert subscriptions. Elke subscription correspondeert met een channel aan de serverzijde. ```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", `
${data.user}: ${data.body}
` ) }, sendMessage(body) { // Calls ChatChannel#receive on the server this.perform("receive", { body: body }) } } ) ``` De `received`-callback wordt elke keer geactiveerd wanneer de server naar de geabonneerde stream verstuurt. De `perform`-methode stuurt gegevens van client naar server en roept de bijbehorende channel-methode aan. ## Solid Cable in Rails 8: Database-Gebaseerde Pub/Sub Rails 8 introduceert Solid Cable als onderdeel van de "Solid Trifecta" naast Solid Queue en Solid Cache. Solid Cable vervangt Redis als pub/sub-backend door berichten op te slaan in een databasetabel. ```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 werkt door elk broadcast-bericht naar een databasetabel te schrijven en op een configureerbaar interval te pollen voor nieuwe berichten. Het standaard polling-interval van 100ms biedt voor de meeste applicaties een nagenoeg realtime aflevering. De afweging is duidelijk: Solid Cable elimineert een infrastructuurafhankelijkheid (Redis) ten koste van iets hogere latentie en databasebelasting. Voor applicaties die al PostgreSQL of MySQL draaien, is deze afweging vaak zinvol. Bij hoogfrequente broadcasting (duizenden berichten per seconde) blijft Redis de betere keuze. ```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 gebruikt een aparte database om conflicten met de primaire database te voorkomen. Deze scheiding voorkomt dat message-polling interfereert met applicatiequery's. ## Broadcasting-Patronen en Serversijdige Triggers Broadcasting vanuit models, jobs en controllers bestrijkt de drie meest voorkomende patronen in productie Rails-applicaties. ```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 ``` Model-callbacks zijn geschikt voor eenvoudige notificaties die worden geactiveerd door recordwijzigingen. Background jobs verwerken zwaardere berekeningen — zoals dashboardstatistieken of data-aggregaties — zonder de request-cyclus te blokkeren. De broadcast zelf is altijd lichtgewicht: het serialiseert de payload en publiceert deze via de adapter. ## Turbo Streams en Action Cable-Integratie Rails 8 met Hotwire gebruikt Action Cable als transportlaag voor Turbo Streams, waardoor realtime DOM-updates mogelijk worden zonder aangepast JavaScript te schrijven. ```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 %>
<%= render @chat_room.messages %>
``` De `broadcasts_to`-macro genereert after_create-, after_update- en after_destroy-callbacks die Turbo Stream-fragmenten via Action Cable verzenden. De `turbo_stream_from`-helper aan de clientzijde abonneert zich op de bijbehorende stream. Het aanmaken van een nieuw bericht voegt automatisch de gerenderde partial toe aan de DOM van elke verbonden client. Dit patroon reduceert realtime functionaliteiten tot een model-declaratie en een view-helper — geen aangepaste channels, geen JavaScript-handlers, geen handmatige DOM-manipulatie. ## Schaling van Action Cable in Productie Productie-deployments vereisen zorgvuldige afwegingen met betrekking tot adapterkeuze, verbindingslimieten en horizontale schaling. ```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 ``` Redis fungeert als pub/sub-backbone en zorgt ervoor dat berichten die op het ene Rails-proces worden gepubliceerd, subscribers bereiken die met een ander proces zijn verbonden. Zonder Redis (of Solid Cable) beperkt de async-adapter broadcasting tot een enkel proces — onbruikbaar in elke multi-proces of multi-server omgeving. Verbindingslimieten hangen af van de server. Puma met Action Cable verwerkt WebSocket-verbindingen op hetzelfde proces als HTTP-verzoeken. Elke WebSocket-verbinding houdt een persistente verbinding in stand en verbruikt een thread (of een fiber in Ruby 3.x met fiber-gebaseerde schedulers). Een typische Puma-configuratie met 5 threads en 4 workers kan ongeveer 200 gelijktijdige WebSocket-verbindingen verwerken voordat verzadiging optreedt. Voor applicaties die duizenden gelijktijdige verbindingen nodig hebben, vervangt [AnyCable](https://anycable.io/) de Ruby WebSocket-server door een Go-gebaseerde server, die verbindingen op protocolniveau beheert terwijl de channel-logica via gRPC wordt teruggestuurd naar Rails. Deze architectuur ondersteunt meer dan 10.000 gelijktijdige verbindingen per node. > **Interview-Inzicht** > > Interviewers vragen regelmatig naar de schaalbaarheidslimieten van Action Cable. Het kernantwoord: Action Cable zelf is niet het knelpunt — het Ruby-proces dat de WebSocket-verbindingen beheert wel. AnyCable lost dit op door verbindingsbeheer uit te besteden aan Go terwijl de channel-logica in Ruby blijft. ## Testen van Action Cable Channels Rails biedt `ActionCable::Channel::TestCase` voor het testen van channels en `ActionCable::Connection::TestCase` voor het testen van verbindingsauthenticatie. ```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 ``` De methode `stub_connection` stelt de verbindingscontext in zonder een echte WebSocket-verbinding. `assert_has_stream_for` verifieert de stream-binding. `assert_broadcast_on` vangt broadcasts op binnen een blok en bevestigt dat de juiste payload de juiste stream bereikt. ## Veelgestelde Sollicitatievragen over Action Cable Technische sollicitatiegesprekken over Action Cable toetsen doorgaans het begrip van het protocol, architectuurbeslissingen en productiegerelateerde vraagstukken. **Hoe authenticeert Action Cable verbindingen?** Authenticatie vindt plaats in `ApplicationCable::Connection#connect` tijdens de WebSocket-handshake. Cookies van de HTTP-sessie zijn op dit moment beschikbaar. Token-gebaseerde authenticatie geeft het token door als queryparameter in de WebSocket-URL en valideert het in `connect`. **Wat gebeurt er wanneer een WebSocket-verbinding wegvalt?** De clientbibliotheek implementeert automatische herverbinding met exponentieel backoff. Aan de serverzijde wordt `unsubscribed` geactiveerd voor elk channel waarop de verbinding was geabonneerd. Stateful opruimacties (gebruikers als offline markeren, locks vrijgeven) horen in `unsubscribed`. **Wanneer moet Solid Cable worden gebruikt in plaats van Redis?** Solid Cable is geschikt voor applicaties met gematigde realtime behoeften (minder dan 100 berichten/seconde) die Redis-infrastructuur willen vermijden. Redis blijft noodzakelijk voor scenario's met hoge doorvoer of wanneer een afleveringslatentie van minder dan 10ms vereist is. > **Veelgemaakte Fout** > > Autorisatielogica in de connection-klasse plaatsen in plaats van in individuele channels. De connection authenticeert de identiteit (Wie is deze gebruiker?). Channels autoriseren de toegang (Mag deze gebruiker deze ruimte betreden?). Het vermengen van deze verantwoordelijkheden creëert beveiligingslekken. ## Conclusie - Action Cable verpakt het WebSocket-protocol in Rails-conventies met connections, channels en subscriptions als kernabstracties - Authenticatie hoort in `ApplicationCable::Connection`; autorisatie hoort in de `subscribed`-callbacks van individuele channels - Solid Cable in Rails 8 elimineert de Redis-afhankelijkheid door de database te gebruiken voor pub/sub — geschikt voor applicaties met gematigde doorvoer - Turbo Streams benutten Action Cable voor automatische realtime DOM-updates met minimale code - Productieschaling vereist Redis of Solid Cable voor multi-proces deployments; AnyCable verwerkt meer dan 10.000 verbindingen door WebSocket-beheer uit te besteden aan Go - Het testen van channels maakt gebruik van `stub_connection`, `assert_has_stream_for` en `assert_broadcast_on` — geen echte WebSocket-verbindingen nodig - [Oefen ActionCable- en WebSocket-sollicitatievragen](/nl/technologies/ruby-on-rails/interview-questions/action-cable-websockets) om deze concepten te versterken met gerichte oefeningen --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/nl/blog/ruby-on-rails/action-cable-websockets-complete-guide