WebSockets ve WebRTC Gerçek Zamanlı

Gerçek zamanlı uygulama geliştirmede WebSockets, Server-Sent Events (SSE) ve WebRTC nedir? Canlı sohbet, anlık bildirim, görüntülü görüşme ve düşük gecikme.

Yozel

12 dakika

WebSockets ve WebRTC Gerçek Zamanlı
İçindekiler (17)

Kullanıcıların bir web sayfasını yenileyerek (F5) yeni bildirimleri veya mesajları kontrol ettiği dönemler çoktan tarihe karıştı. Günümüzde finansal borsa ekranlarından çok oyunculu çevrimiçi oyunlara, üretken yapay zeka (LLM) sohbet arayüzlerinden canlı kurye takibine ve yüksek çözünürlüklü video konferans platformlarına kadar her modern sistem gerçek zamanlı (real-time) ve milisaniye altı gecikmeli (sub-millisecond latency) veri akışı üzerine inşa ediliyor. Ancak gerçek zamanlı bir mimari tasarlarken tüm senaryoları tek bir ağ protokolüyle çözmeye çalışmak büyük bir mühendislik hatasıdır. Uygulama ve yazılım geliştirme süreçlerinde WebSockets, Server-Sent Events (SSE) ve WebRTC protokollerinin OSI ağ katmanındaki davranışlarını, TCP/UDP farklarını ve ölçekleme darboğazlarını doğru analiz etmek hayati önem taşır.

Bu kapsamlı mühendislik rehberinde; geleneksel HTTP Polling yöntemlerinin neden yüksek ölçekte çöktüğünü, WebSockets'in çift yönlü (full-duplex) kalıcı TCP tünelini, yapay zeka token akışlarında neden SSE'nin (Server-Sent Events) tercih edildiğini ve WebRTC'nin STUN, TURN, ICE ile SFU medya sunucularını kullanarak UDP üzerinden nasıl uçtan uca (Peer-to-Peer) ses/görüntü aktardığını tüm teknik derinliğiyle inceleyeceğiz.

1. Neden Geleneksel HTTP İstek-Yanıt (Request-Response) Modeli Yetersiz Kalır?

Web'in temel taşı olan HTTP/1.1 protokolü doğası gereği istemci başlatmalı (client-initiated) ve durumsuz (stateless) bir protokoldür: İstemci (tarayıcı veya mobil uygulama) bir istek gönderir, sunucu yanıtı döner ve işlem tamamlanır. Sunucunun kendi inisiyatifiyle istemciye "Yeni bir siparişin var!" veya "Borsa fiyatı değişti!" deme şansı yoktur. Gerçek zamanlı protokoller yaygınlaşmadan önce mühendisler bu kısıtlamayı aşmak için iki geçici çözüm (workaround) kullanıyordu:

  • Short Polling (Kısa Aralıklı Yoklama): İstemci her 2-3 saniyede bir `setInterval` ile sunucuya `GET /api/notifications` isteği atar. Eğer 100.000 aktif kullanıcınız varsa ve %99'una o saniye yeni bildirim gelmemişse bile, sunucularınız saniyede on binlerce boş HTTP başlığı (HTTP Headers), TLS el sıkışması ve veritabanı sorgusu işleyerek kendi kendine DDoS saldırısı yapmış olur.
  • HTTP Long Polling (Uzun Yoklama): İstemci sunucuya istek atar; sunucu yeni bir veri gelene kadar (veya 30 saniyelik zaman aşımı dolana kadar) bağlantıyı açık tutar (hanging GET). Veri geldiği anda yanıt döner ve istemci anında yeni bir bağlantı açar. Short Polling'e göre daha verimli olsa da yoğun mesajlaşma trafiğinde sürekli TCP/HTTP yeniden kurulum yükü (overhead) yaratır.

Modern gerçek zamanlı sistemler bu verimsizliği ortadan kaldırmak için uygulama katmanında WebSockets, Server-Sent Events (SSE) ve taşıma katmanında UDP tabanlı WebRTC mimarilerine geçmiştir.

WebSocket Çift Yönlü Tam Dubleks Bağlantı ve SSE Karşılaştırması
WebSockets tek bir TCP bağlantısı üzerinden çift yönlü (Full-Duplex) düşük gecikmeli çerçeve iletimi sağlarken, SSE standart HTTP üzerinden sunucudan istemciye tek yönlü (Unidirectional) akış sunar.

2. WebSockets (RFC 6455): Kalıcı ve Tam Çift Yönlü (Full-Duplex) TCP İletişimi

WebSocket, istemci ile sunucu arasında tek bir TCP bağlantısı üzerinden tam çift yönlü (full-duplex), yani her iki tarafın da aynı anda birbirinden bağımsız olarak veri gönderebildiği kalıcı bir iletişim kanalı kuran protokoldür (`ws://` veya şifreli `wss://`).

HTTP Upgrade El Sıkışması (Handshake) ve Çerçeveleme (Framing)

Bir WebSocket bağlantısı hayatına standart bir HTTP/1.1 `GET` isteği olarak başlar (böylece kurumsal güvenlik duvarlarını ve 80/443 portlarını sorunsuz geçer). İstemci şu başlıkları gönderir:

GET /realtime/chat HTTP/1.1
Host: api.ornek.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Sunucu bu isteği kabul ettiğinde `HTTP/1.1 101 Switching Protocols` yanıtını döner. Bu andan itibaren HTTP protokolü tamamen devre dışı kalır ve açık olan TCP soketi üzerinden yalnızca 2 ila 14 baytlık minimal başlık yüküne (frame header) sahip ikili (binary) veya metin (UTF-8 JSON) çerçeveleri (frames) akmaya başlar. Her mesajda yüzlerce baytlık HTTP Cookie ve Header taşıma zorunluluğu ortadan kalktığı için ağ bant genişliği tüketimi %90'a varan oranda düşer ve gecikme süresi birkaç milisaniyeye iner.

WebSockets'i Yatayda Ölçeklemek: Redis Pub/Sub ve Durum (State) Sorunu

Durumsuz (stateless) REST API'leri bir yük dengeleyici (Load Balancer) arkasında 10 sunucuya ölçeklemek çok kolaydır. Ancak WebSockets durumlu (stateful) bir bağlantıdır! Ahmet 1. sunucuya (`Server-A`), Mehmet ise 2. sunucuya (`Server-B`) bağlıysa; Ahmet'in gönderdiği mesajı `Server-A` doğrudan Mehmet'e iletemez. Bu mimari sorunu çözmek için arka uçta Redis Pub/Sub, NATS veya Apache Kafka gibi bir mesaj omurgası (message broker) kullanılır:

// Node.js / TypeScript: Redis Pub/Sub ile Yatay Ölçeklenebilir WebSocket Sunucusu
import { WebSocketServer, WebSocket } from "ws";
import Redis from "ioredis";

const pub = new Redis(process.env.REDIS_URL!);
const sub = new Redis(process.env.REDIS_URL!);
const wss = new WebSocketServer({ port: 8080 });

const localClients = new Map<string, WebSocket>();

sub.subscribe("global-chat-room");
sub.on("message", (_channel, message) => {
  const payload = JSON.parse(message);
  const targetSocket = localClients.get(payload.recipientId);
  if (targetSocket && targetSocket.readyState === WebSocket.OPEN) {
    targetSocket.send(JSON.stringify(payload));
  }
});

wss.on("connection", (ws, req) => {
  const userId = new URL(req.url!, "http://localhost").searchParams.get("userId")!;
  localClients.set(userId, ws);

  ws.on("message", async (raw) => {
    // Mesajı tüm sunucu düğümlerine (nodes) yayınla
    await pub.publish("global-chat-room", raw.toString());
  });

  ws.on("close", () => localClients.delete(userId));
});

Ayrıca kopan bağlantıları (half-open TCP connections) tespit etmek için sunucu ve istemci arasında düzenli aralıklarla (örneğin her 30 saniyede bir) Ping / Pong (Heartbeat) çerçeveleri gönderilmeli ve mobil cihazlarda internet koptuğunda Exponential Backoff + Jitter (Üstel Geri Çekilme) algoritmasıyla yeniden bağlanma (reconnection) yönetilmelidir.

3. Server-Sent Events (SSE): Tek Yönlü Akışın ve Yapay Zeka (LLM) Arayüzlerinin Yıldızı

Birçok yazılım mühendisi gerçek zamanlı bir ihtiyaç duyduğunda refleks olarak hemen WebSocket kurar. Oysa uygulamanızda veri akışı yalnızca sunucudan istemciye doğruysa (Unidirectional) — örneğin canlı maç skorları, kripto/borsa fiyat akışı, sipariş durumu bildirimleri veya ChatGPT/Claude tarzı üretken yapay zeka kelime akışı (token streaming) — WebSocket kurmak gereksiz bir mühendislik karmaşıklığıdır. Bu senaryoların tartışmasız şampiyonu Server-Sent Events (SSE) standardıdır.

Neden SSE Birçok Senaryoda WebSocket'ten Daha Üstündür?

  • Saf HTTP Protokolü (`text/event-stream`): SSE özel bir `ws://` protokolüne geçiş yapmaz; standart HTTP/2 ve HTTP/3 üzerinden çalışır. Kurumsal proxy'ler, güvenlik duvarları ve CDN'ler tarafından engellenmez.
  • HTTP/2 Çoklama (Multiplexing) Avantajı: HTTP/2 üzerinde çalışan SSE, aynı alan adına yapılan diğer REST API çağrılarıyla tek bir TCP bağlantısını paylaşır (multiplexing).
  • Yerleşik Otomatik Yeniden Bağlanma ve `Last-Event-ID`: Tarayıcıdaki yerel `EventSource` API'si, bağlantı koptuğunda tek satır ekstra kod yazmanıza gerek kalmadan otomatik olarak yeniden bağlanır ve son aldığı olayın kimliğini (`Last-Event-ID` başlığı) sunucuya göndererek kayıp mesajların kaldığı yerden devam etmesini sağlar.

Özellikle modern API ve olay güdümlü e-ticaret mimarilerinde stok değişimleri, flaş indirim sayaçları ve yapay zeka alışveriş asistanları için SSE hem sunucu kaynaklarını korur hem de istemci tarafı performans metriklerini yormaz.

WebRTC P2P STUN TURN ve SFU Medya Sunucusu Mimarisi
WebRTC, STUN ve TURN sunucularıyla NAT/Güvenlik Duvarı engellerini aşarak UDP üzerinden ultra düşük gecikmeli ses, görüntü ve veri kanalı (DataChannel) iletişimi kurar.

4. WebRTC (Web Real-Time Communication): UDP Üzerinden Uçtan Uca Ses, Video ve Veri

WebSockets ve SSE, güvenilir veri iletimi sağlayan TCP (Transmission Control Protocol) üzerinde çalışır. TCP, gönderilen her paketin sırasıyla ve eksiksiz ulaşmasını garanti eder; ancak yolda tek bir paket kaybolursa, o paket yeniden gönderilene kadar arkadan gelen tüm yeni paketleri bekletir. Bu duruma Head-of-Line (HoL) Blocking (Sıra Başı Bloklaması) denir. Metin mesajlaşmada 200 milisaniyelik bir gecikme fark edilmez; ancak canlı bir görüntülü görüşmede veya bulut oyun (Cloud Gaming) akışında 1 saniye önceki kayıp bir video karesini beklemek görüntünün tamamen donmasına yol açar!

Canlı ses ve görüntülü iletişimde "hız, kusursuzluktan önemlidir". İşte bu yüzden WebRTC, TCP yerine UDP (User Datagram Protocol) tabanlı güvenli iletişim protokollerini (SRTP ve DTLS/SCTP) kullanır ve veriyi merkezi bir sunucuya uğratmadan doğrudan iki tarayıcı/cihaz arasında Uçtan Uca (Peer-to-Peer / P2P) aktarabilir.

Sinyalleşme (Signaling), STUN, TURN ve ICE Mimarisi

İki kullanıcının (örneğin İstanbul'daki Ayşe ile Berlin'deki Can) tarayıcılarının doğrudan birbirine UDP paketi gönderebilmesi için önce birbirlerinin genel IP adreslerini, portlarını ve destekledikleri ses/video kodeklerini (Opus, VP8, VP9, H.264, AV1) öğrenmeleri gerekir. Ev ve ofis modemlerindeki NAT (Network Address Translation) ve güvenlik duvarları cihazların gerçek IP adreslerini gizlediği için WebRTC dört aşamalı bir mekanizma işletir:

  1. Signaling (Sinyalleşme Sunucusu): WebRTC standardı sinyalleşmenin nasıl yapılacağını dayatmaz; genellikle küçük bir WebSocket sunucusu üzerinden iki cihaz birbirine SDP (Session Description Protocol) Offer/Answer nesnelerini göndererek medya yeteneklerini el sıkışır.
  2. STUN (Session Traversal Utilities for NAT): İstemci, hafif bir STUN sunucusuna "Dış dünyadan benim genel IP adresim ve portum ne görünüyor?" diye sorar. Bağlantıların yaklaşık %80'i STUN ile keşfedilen adresler üzerinden doğrudan P2P olarak kurulur.
  3. TURN (Traversal Using Relays around NAT): Eğer taraflardan biri katı bir kurumsal güvenlik duvarı (Symmetric NAT) arkasındaysa ve doğrudan P2P bağlantı engelleniyorsa, medya paketleri TURN röle sunucusu üzerinden aktarılır.
  4. ICE (Interactive Connectivity Establishment): Tüm olası bağlantı adaylarını (Local IP, STUN Reflexive IP, TURN Relay IP) toplayıp en düşük gecikmeli rotayı otomatik seçen orkestrasyon protokolüdür.

Grup Görüşmelerinde Mesh, MCU ve SFU Mimarileri

İki kişilik görüşmede P2P mükemmel çalışır; ancak 25 kişilik bir toplantıda herkes herkese doğrudan video gönderirse (Mesh Topolojisi), her katılımcının bilgisayarı aynı anda 24 ayrı video akışı yüklemek (upload) ve 24 akış çözmek (decode) zorunda kalır ki bu da işlemciyi ve interneti anında kilitler. Bu nedenle ölçeklenebilir WebRTC platformları (Zoom, Google Meet, LiveKit, Mediasoup, Pion) ortada bir SFU (Selective Forwarding Unit - Seçici İletim Birimi) medya sunucusu kullanır. Her katılımcı videosunu yalnızca SFU sunucusuna gönderir; SFU ise videoyu yeniden kodlamadan (transcoding yapmadan) Simulcast / SVC teknolojisiyle diğer katılımcıların ekran boyutuna ve internet hızına uygun katmanı seçerek dağıtır.

5. Üretim Ortamında Gerçek Zamanlı Sistem Güvenliği, Geri Basınç (Backpressure) ve Sıfır Kesintili Dağıtım

Gerçek zamanlı bir prototip geliştirmek kolaydır; ancak aynı anda 500.000 açık bağlantıyı üretim ortamında çökmeden yönetmek ciddi bir sistem mühendisliği disiplini gerektirir. Üretim (production) seviyesinde mutlaka uygulanması gereken üç kritik mekanizma şunlardır:

  • Geri Basınç (Backpressure) ve Yavaş İstemci Yönetimi: Sunucunuz saniyede 1.000 finansal fiyat güncellemesi üretirken, mobil ağdaki (3G/Edge) bir kullanıcının interneti bu paketleri aynı hızda okuyamıyorsa, gönderilmeyi bekleyen mesajlar sunucunun TCP gönderim tamponunda (`ws.bufferedAmount`) birikmeye başlar. Eğer binlerce yavaş istemci için sunucu RAM'inde sınırsız kuyruk tutarsanız sunucunuz Out-Of-Memory (OOM) hatasıyla çöker. Bu nedenle `ws.bufferedAmount` belirli bir eşiği (örneğin 1 MB) aştığında eski fiyat paketlerini düşürmek (dropping stale frames) veya bağlantıyı kontrollü şekilde sonlandırmak şarttır.
  • WebSocket Güvenliği (CSWSH ve Kimlik Doğrulama): Tarayıcıdaki yerel `WebSocket` API'si özel `Authorization: Bearer ...` HTTP başlığı göndermeyi doğrudan desteklemez. Bu nedenle kimlik doğrulama için kısa ömürlü (30 saniyelik) tek kullanımlık Ticket (Bilet) Token deseni veya `Sec-WebSocket-Protocol` alt protokol alanı kullanılmalı ve Cross-Site WebSocket Hijacking (CSWSH) saldırılarını önlemek için el sıkışma sırasında `Origin` başlığı mutlaka sunucu tarafında doğrulanmalıdır.
  • Sıfır Kesintili Dağıtım (Connection Draining & Thundering Herd): Yeni bir yazılım sürümü yayınlarken 50.000 kullanıcının bağlı olduğu bir WebSocket sunucusunu aniden kapatırsanız, 50.000 cihaz aynı saniyede diğer sunuculara yeniden bağlanmaya çalışır. Thundering Herd (Ürkek Sürü) adı verilen bu dalga tüm yük dengeleyicinizi kilitleyebilir. Bunun yerine sunucu kapatılmadan önce kademeli olarak istemcilere "5-60 saniye arasında rastgele bir sürede (Jitter) yeniden bağlan" komutu gönderilerek trafik yumuşakça yeni düğümlere aktarılır.

6. Kapsamlı Karşılaştırma Tablosu: WebSockets vs SSE vs WebRTC

Gerçek zamanlı sistem mimarinizde hangi protokolü seçmeniz gerektiğini aşağıdaki karar tablosu üzerinden netleştirebilirsiniz:

Özellik / Kriter WebSockets Server-Sent Events (SSE) WebRTC (Media & DataChannel)
İletişim Yönü Çift Yönlü (Full-Duplex) Tek Yönlü (Sunucudan İstemciye) Çift Yönlü (Uçtan Uca P2P veya SFU)
Taşıma Katmanı Protokolü TCP (`ws://` ve `wss://`) Standart HTTP/1.1, HTTP/2, HTTP/3 UDP (SRTP, SCTP over DTLS)
Sıra Başı Bloklaması (HoL) Var (TCP kaynaklı) HTTP/1.1'de var, HTTP/3 (QUIC) ile yok Yok (Kayıp paketler akışı durdurmaz)
Veri Formatı UTF-8 Metin ve İkili (Binary) UTF-8 Metin (`text/event-stream`) Ses, Video ve İkili/Metin (`RTCDataChannel`)
Otomatik Yeniden Bağlanma Yok (Manuel kodlanmalı / Socket.IO) Tarayıcıda Yerleşik (`EventSource`) ICE Restart ile manuel yönetilir
Güvenlik Duvarı / Proxy Uyumu Orta-Yüksek (Bazı eski vekiller kesebilir) Mükemmel (Standart HTTP trafiği) Zor (STUN/TURN altyapısı şarttır)
En İdeal Kullanım Alanı Sohbet uygulamaları, ortak çalışma araçları (Figma/Notion), canlı destek Yapay zeka (LLM) akışı, canlı borsa/skor tabelası, anlık bildirimler Görüntülü/sesli görüşme, ekran paylaşımı, P2P dosya aktarımı, hızlı oyunlar

6. Sıkça Sorulan Sorular (SSS)

1. Socket.IO ile saf (native) WebSocket aynı şey midir?

Hayır. Socket.IO, WebSocket protokolünün üzerine inşa edilmiş, otomatik yeniden bağlanma, odalar (rooms/namespaces), paket tamponlama ve WebSocket engellendiğinde HTTP Long Polling'e geri düşme (fallback) özellikleri sunan üst seviye bir kütüphanedir. Özel bir üst bilgi kullandığı için standart bir `new WebSocket()` istemcisi doğrudan bir Socket.IO sunucusuna bağlanamaz.

2. WebRTC sadece ses ve görüntü için mi kullanılır?

Hayır! WebRTC'nin `RTCDataChannel` API'si, iki tarayıcı arasında UDP (SCTP) üzerinden istediğiniz herhangi bir JSON metnini veya ikili dosyayı (binary file) sunucuya hiç uğratmadan P2P olarak göndermenizi sağlar. Özellikle merkezsiz Web3 ağlarında, tarayıcı içi P2P dosya paylaşım araçlarında ve düşük gecikmeli çok oyunculu tarayıcı oyunlarında `RTCDataChannel` yoğun olarak kullanılır.

3. Sunucusuz (Serverless - AWS Lambda / Vercel Functions) mimarilerde WebSocket nasıl kullanılır?

Geleneksel Serverless fonksiyonlar yalnızca birkaç saniye yaşayıp kapandığı için milyonlarca kalıcı WebSocket bağlantısını üzerlerinde tutamazlar. Bu mimaride bağlantı durumunu yönetmek için AWS API Gateway WebSocket API, Cloudflare Durable Objects veya Pusher, Ably, Supabase Realtime gibi yönetilen uç servisler kullanılır.

4. SSE (Server-Sent Events) bağlantısında tarayıcıların 6 bağlantı sınırı sorunu hala geçerli mi?

Klasik HTTP/1.1 protokolünde tarayıcılar alan adı (domain) başına maksimum 6 eşzamanlı bağlantıya izin verirdi; bu da kullanıcı 6 sekme açtığında SSE'nin tıkanmasına yol açardı. Ancak günümüzde tüm modern sunucular ve CDN'ler HTTP/2 ve HTTP/3 kullandığı için tüm sekmelerdeki SSE akışları tek bir TCP/QUIC bağlantısı üzerinden çoklanır (multiplexed) ve 6 sekme sınırı tamamen ortadan kalkar.

5. WebTransport protokolü gelecekte WebSockets ve WebRTC'nin yerini alacak mı?

WebTransport, HTTP/3 ve QUIC (UDP) protokolü üzerine inşa edilen yeni nesil bir W3C standardıdır. Hem WebSocket gibi kolayca istemci-sunucu bağlantısı kurar hem de WebRTC gibi sıra başı bloklaması (Head-of-Line blocking) olmayan güvenilir akışlar (streams) ve güvenilmez UDP datagramları gönderebilir. Önümüzdeki yıllarda özellikle bulut oyun, canlı yayın ve düşük gecikmeli sunucu iletişiminde WebSocket'in en güçlü alternatifi olacaktır.

Paylaş

Yozel

Codex haberleri en az iki bağımsız kaynakla doğrulanır; düzeltmeler yazının altında tarih ve saatle belirtilir. Yayın ilkelerimiz