Rails'te Action Cable ve WebSocket'ler: Teknik Mulakat Rehberi 2026
Ruby on Rails'te Action Cable ve WebSocket'lerin derinlemesine incelenmesi. Bağlantılar, kanallar, broadcasting, Rails 8'de Solid Cable, Redis ile ölçeklendirme ve kod örnekleriyle sık sorulan mülakat soruları.

Action Cable, WebSocket desteğini doğrudan Rails framework'üne entegre ederek sohbet, bildirimler ve canlı panolar gibi gerçek zamanlı özelliklerin harici bağımlılıklar olmadan oluşturulmasını sağlar. 2026 teknik mülakatlarında Action Cable'ın iç mekanizmalarını — bağlantı yaşam döngüsünden üretim ortamında ölçeklendirmeye kadar — bilmek, güçlü adayları diğerlerinden ayıran önemli bir faktördür.
Action Cable, WebSocket'leri kontrolcüler ve modeller için kullanılan aynı konvansiyonlarla Rails framework'üne entegre eder. Rails 8, pub/sub mesajlaşması için Redis gereksinimini ortadan kaldıran veritabanı destekli bir adaptör olan Solid Cable'ı tanıtır.
Rails Bağlamında WebSocket Protokolü Temelleri
WebSocket protokolü (RFC 6455), tek bir TCP bağlantısı üzerinden kalıcı, çift yönlü bir iletişim kanalı oluşturur. HTTP'nin istek-yanıt döngüsünün aksine, WebSocket'ler açık bir bağlantı sürdürerek hem istemcinin hem de sunucunun herhangi bir anda mesaj göndermesine olanak tanır.
Action Cable bu protokolü Rails'e uygun bir soyutlamaya dönüştürür. Sunucu, /cable adresinde WebSocket yükseltmelerini yönetir, bağlantı kimlik doğrulamasını kontrol eder ve mesajları kanallar üzerinden yönlendirir. İstemci tarafındaki JavaScript kütüphanesi abonelikleri otomatik olarak oluşturur ve yönetir.
Tipik bir HTTP isteği milisaniyeler içinde tamamlanır ve kapanır. WebSocket bağlantısı ise dakikalarca, saatlerce veya tüm oturum boyunca açık kalır. Bu temel fark, Action Cable'daki her mimari kararı belirler.
Action Cable Mimarisi: Bağlantılar, Kanallar ve Abonelikler
Action Cable, üç temel soyutlamaya sahip katmanlı bir mimari izler: bağlantılar kimlik doğrulamayı yönetir, kanallar iş mantığını kapsüller ve abonelikler tüketicileri belirli kanallara bağlar.
# 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
endBağlantı sınıfı, WebSocket el sıkışması sırasında bir kez çalışır. Kimlik doğrulama burada gerçekleşir — bireysel kanallarda değil. identified_by bildirimi kullanıcı kimliğini kaydederek o bağlantıdaki tüm kanal aboneliklerinde erişilebilir kılar.
# 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
endKanallar üç yaşam döngüsü callback'i tanımlar: subscribed, receive ve unsubscribed. stream_for metodu aboneliği belirli bir model örneğine bağlayarak isim alanlı bir akış oluşturur. Bu akışa yapılan broadcast, bağlı her aboneye mesajları iletir.
JavaScript ile İstemci Tarafı Abonelikler
İstemci tarafındaki tüketici, Action Cable sunucusuna bağlanır ve abonelikleri yönetir. Her abonelik, sunucu tarafındaki bir kanala karşılık gelir.
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",
`<div class="message"><strong>${data.user}</strong>: ${data.body}</div>`
)
},
sendMessage(body) {
// Calls ChatChannel#receive on the server
this.perform("receive", { body: body })
}
}
)received callback'i, sunucu abone olunan akışa her broadcast yaptığında tetiklenir. perform metodu istemciden sunucuya veri göndererek ilgili kanal metodunu çağırır.
Ruby on Rails mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Rails 8'de Solid Cable: Veritabanı Destekli Pub/Sub
Rails 8, Solid Queue ve Solid Cache ile birlikte "Solid Trifecta"nın bir parçası olarak Solid Cable'ı sunar. Solid Cable, mesajları bir veritabanı tablosunda depolayarak Redis'in yerine pub/sub arka ucu olarak görev yapar.
# 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.daySolid Cable, her broadcast mesajını bir veritabanı tablosuna yazarak ve yapılandırılabilir bir aralıkta yeni mesajları sorgulayarak çalışır. Varsayılan 100ms'lik sorgulama aralığı, çoğu uygulama için neredeyse gerçek zamanlı teslimat sağlar.
Ödünleşim açıktır: Solid Cable bir altyapı bağımlılığını (Redis) ortadan kaldırırken, biraz daha yüksek gecikme ve veritabanı yükü getirir. Zaten PostgreSQL veya MySQL kullanan uygulamalar için bu ödünleşim genellikle mantıklıdır. Yüksek frekanslı broadcasting (saniyede binlerce mesaj) için Redis daha iyi bir seçim olmaya devam eder.
# config/database.yml (Rails 8 multi-database)
production:
primary:
<<: *default
database: myapp_production
cable:
<<: *default
database: myapp_cable_production
migrations_paths: db/cable_migrateSolid Cable, birincil veritabanı ile çakışmayı önlemek için ayrılmış bir veritabanı kullanır. Bu ayrım, mesaj sorgulamasının uygulama sorgularını etkilemesini önler.
Broadcasting Kalıpları ve Sunucu Tarafı Tetikleyiciler
Modeller, arka plan görevleri ve kontrolcülerden broadcasting, üretim Rails uygulamalarında en yaygın üç kalıbı kapsar.
# 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
endModel callback'leri, kayıt değişiklikleriyle tetiklenen basit bildirimler için uygundur. Arka plan görevleri ise daha ağır hesaplamaları — pano istatistiklerinin hesaplanması veya verilerin toplanması gibi — istek döngüsünü engellemeden yönetir. Broadcast'in kendisi her zaman hafiftir: payload'ı serileştirir ve adaptöre yayınlar.
Turbo Streams ve Action Cable Entegrasyonu
Hotwire ile Rails 8, Turbo Streams için taşıma katmanı olarak Action Cable'ı kullanarak özel JavaScript yazmadan gerçek zamanlı DOM güncellemeleri yapılmasını sağlar.
# 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 %>
<div id="messages">
<%= render @chat_room.messages %>
</div>broadcasts_to makrosu, Turbo Stream fragmanlarını Action Cable üzerinden broadcast eden after_create, after_update ve after_destroy callback'leri oluşturur. İstemci tarafındaki turbo_stream_from helper'ı eşleşen akışa abone olur. Yeni bir mesaj oluşturulduğunda, render edilmiş partial otomatik olarak bağlı her istemcinin DOM'una eklenir.
Bu kalıp, gerçek zamanlı özellikleri bir model bildirimi ve bir view helper'ına indirger — özel kanallar, JavaScript handler'ları veya manuel DOM manipülasyonu gerekmez.
Üretim Ortamında Action Cable'ı Ölçeklendirme
Üretim dağıtımları, adaptör seçimi, bağlantı limitleri ve yatay ölçeklendirme konularında dikkatli değerlendirme gerektirir.
# config/cable.yml — Redis adapter for high-scale production
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: myapp_productionRedis, pub/sub omurgası olarak görev yapar ve bir Rails sürecinde yayınlanan mesajların diğer herhangi bir sürece bağlı abonelere ulaşmasını sağlar. Redis (veya Solid Cable) olmadan, async adaptör broadcasting'i tek bir süreçle sınırlar — bu da çoklu süreç veya çoklu sunucu dağıtımlarında kullanılamaz.
Bağlantı limitleri sunucuya bağlıdır. Action Cable ile Puma, WebSocket bağlantılarını HTTP istekleriyle aynı süreçte yönetir. Her WebSocket kalıcı bir bağlantı tutar ve bir iş parçacığı (veya Ruby 3.x'te fiber tabanlı zamanlayıcılarla bir fiber) tüketir. 5 iş parçacığı ve 4 worker'lı tipik bir Puma yapılandırması, doygunluktan önce yaklaşık 200 eşzamanlı WebSocket bağlantısını yönetebilir.
Binlerce eşzamanlı bağlantı gerektiren uygulamalar için AnyCable, Ruby WebSocket sunucusunun yerini Go tabanlı bir sunucu ile alır. Bağlantıları protokol düzeyinde yönetirken kanal mantığını gRPC aracılığıyla Rails'e geri yönlendirir. Bu mimari, düğüm başına 10.000'den fazla eşzamanlı bağlantıyı destekler.
Mülakatçılar sıklıkla Action Cable ölçeklendirme limitleri hakkında soru sorar. Anahtar cevap: Action Cable'ın kendisi darboğaz değildir — darboğaz, WebSocket bağlantılarını yöneten Ruby sürecidir. AnyCable, bağlantı yönetimini Go'ya taşıyarak ve kanal mantığını Ruby'de tutarak bu sorunu çözer.
Action Cable Kanallarını Test Etme
Rails, kanalların birim testi için ActionCable::Channel::TestCase ve bağlantı kimlik doğrulaması için ActionCable::Connection::TestCase sağlar.
# 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
endstub_connection metodu, gerçek bir WebSocket olmadan bağlantı bağlamını kurar. assert_has_stream_for akış bağlamasını doğrular. assert_broadcast_on bir blok içindeki broadcast'leri yakalar ve doğru payload'ın doğru akışa ulaştığını onaylar.
Action Cable Hakkında Sık Sorulan Mülakat Soruları
Action Cable hakkındaki teknik mülakat soruları genellikle protokol anlayışını, mimari kararları ve üretim ortamı endişelerini araştırır.
Action Cable bağlantıları nasıl doğrular? Kimlik doğrulama, WebSocket el sıkışması sırasında ApplicationCable::Connection#connect metodunda gerçekleşir. Bu noktada HTTP oturumundan gelen çerezler mevcuttur. Token tabanlı kimlik doğrulama, token'ı WebSocket URL'sinde sorgu parametresi olarak iletir ve connect metodunda doğrular.
WebSocket bağlantısı koptuğunda ne olur? İstemci kütüphanesi, üstel geri çekilme ile otomatik yeniden bağlantı uygular. Sunucu tarafında, bağlantının abone olduğu her kanal için unsubscribed tetiklenir. Durum bilgisi içeren temizlik (kullanıcıları çevrimdışı olarak işaretleme, kilitleri serbest bırakma) unsubscribed metoduna yerleştirilmelidir.
Solid Cable ne zaman Redis yerine tercih edilmelidir? Solid Cable, Redis altyapısından kaçınmak isteyen orta düzey gerçek zamanlı ihtiyaçları olan uygulamalar (saniyede 100'den az mesaj) için uygundur. Yüksek verimlilik senaryolarında veya 10ms altı teslimat gecikmesinin önemli olduğu durumlarda Redis gerekli olmaya devam eder.
Yetkilendirme mantığının bireysel kanallar yerine bağlantı sınıfına yerleştirilmesi. Bağlantı kimliği doğrular (bu kullanıcı kim?). Kanallar erişimi yetkilendirir (bu kullanıcı bu odaya erişebilir mi?). Bu sorumlulukların karıştırılması güvenlik açıkları oluşturur.
Sonuc
- Action Cable, WebSocket protokolünü bağlantılar, kanallar ve abonelikler ile Rails konvansiyonlarına sarar
- Kimlik doğrulama
ApplicationCable::Connection'a aittir; yetkilendirme bireysel kanalsubscribedcallback'lerine aittir - Rails 8'deki Solid Cable, pub/sub için veritabanını kullanarak Redis bağımlılığını ortadan kaldırır — orta verimli uygulamalar için uygundur
- Turbo Streams, minimum kodla otomatik gerçek zamanlı DOM güncellemeleri için Action Cable'ı kullanır
- Üretim ölçeklendirmesi, çoklu süreç dağıtımları için Redis veya Solid Cable gerektirir; AnyCable, WebSocket yönetimini Go'ya taşıyarak 10.000'den fazla bağlantıyı destekler
- Kanal testi
stub_connection,assert_has_stream_forveassert_broadcast_onkullanır — gerçek WebSocket bağlantıları gerekmez - Action Cable ve WebSocket mülakat sorularını pratik yaparak bu kavramları hedefli alıştırmalarla pekiştirmek mümkündür
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Etiketler
Paylaş
İlgili makaleler

2026'da Rails API Modu: RESTful API, Serializasyon ve Mulakat Sorulari
Rails API-only modu ile production-ready RESTful API gelistirme: Alba ve jsonapi-serializer ile JSON serializasyonu, JWT authentication, hata yonetimi ve RSpec testleri.

ActiveRecord: Ruby on Rails'te N+1 Sorgu Sorunlarını Çözmek
Rails'te ActiveRecord ile N+1 sorgularını tespit etme ve çözme rehberi. includes, preload, eager_load ve otomatik tespit araçlarına hâkim olun.

Ruby on Rails Mulakat Sorulari: 2026 En Iyi 25
En cok sorulan 25 Ruby on Rails mulakat sorusu. MVC mimarisi, Active Record, migration, RSpec testi, REST API ayrintili cevaplar ve kod ornekleri ile.