Gerçek zamanlı veri lafı geçince refleksif olarak WebSocket düşünüyoruz. Son üç projemde kullandıktan sonra şunu öğrendim, durumların yarısından fazlasında Server-Sent Events daha doğru karar. Basit, tek yön, HTTP üstünde çalışan, proxy’lerden rahat geçen bir teknoloji. WebSocket’in pahalı kurulumuna ihtiyaç yok.
SSE nedir?
Server sürekli açık bir HTTP connection üzerinden client’a mesaj gönderir. Mesajlar data: ...nn formatında geliyor. Client EventSource objesi ile dinliyor.
const source = new EventSource('/events');
source.onmessage = (e) => console.log(e.data);
source.addEventListener('order-update', (e) => handleOrder(JSON.parse(e.data)));Server tarafında (PHP örneği):
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no');
while (true) {
if ($event = fetchEvent()) {
echo "event: order-updaten";
echo "data: " . json_encode($event) . "nn";
ob_flush(); flush();
}
sleep(1);
}WebSocket vs SSE
| Özellik | SSE | WebSocket |
| — | — | — |
| Yön | Tek yön (server → client) | Çift yön |
| Protokol | HTTP | TCP upgrade, WS/WSS |
| Reconnect | Otomatik (browser kendi yapar) | Manuel yazmak gerek |
| Proxy uyumu | Çok iyi | Orta |
| HTTP/2 multiplexing | Destekli | Ayrı connection |
| Browser limit | Origin başına 6 | Origin başına 200+ |
| Format | Text (UTF-8) | Binary + text |
Tek yön kısıtlaması önemli değil gibi görünür, aslında ekmek teknesi. Notification, live dashboard, order tracking, stock ticker, log streaming. Bunların hiçbiri client’tan yazı beklemez. SSE yeter.
Projeden örnek 1: kargo takip
Bir lojistik şirketinde kargo durumu dashboard’u yaptık. Kullanıcı 50-100 kargo izliyor, her birinin durumu değiştikçe UI güncellensin istiyordu. İlk tasarım WebSocket idi. Prod’a çıkınca sorunlar başladı, müşterilerin corporate firewall’ları WebSocket upgrade paketlerini engelliyordu. SSE’ye geçtik, aynı firewall’dan doğrudan HTTPS trafiği olarak geçti. Tek değişiklik.
Projeden örnek 2: chat uygulaması
Mesajlaşma uygulamasında SSE denedim, iki yönlülük eksikliği çok can sıktı. Her mesaj göndermek için ayrı POST, her yeni mesaj için SSE. Yaklaşım işe yarıyor ama ince ayar çok. WebSocket daha temiz oldu.
Ayrıca tek connection üzerinden typing indicator, read receipt, presence gibi sinyallerin hepsini aynı kanalda göndermek gerekiyordu. SSE ile POST kombinasyonu burada fazla gürültülü.
SSE’nin tuzakları
- HTTP/1.1’de connection limiti. Tarayıcı origin başına 6 HTTP connection açabiliyor. Sitenizde 6 SSE varsa diğer istekler kilitlenir. HTTP/2 kullanmak bunu tamamen çözüyor çünkü multiplex oluyor.
- Proxy buffering. Nginx default buffering açık, SSE akışını tutup toplu gönderiyor.
X-Accel-Buffering: noheader’ı veyaproxy_buffering off;gerekli. - PHP-FPM uzun ömürlü connection’larda rahat değil. Bir işçi süreci o kullanıcı için kitlidir. Yüksek concurrent trafikte PHP-FPM tükenir. Çözüm, ReactPHP, Swoole veya Node.js ile SSE endpoint yazmak. Ana uygulamadan ayrık bir servis olsun.
- Heartbeat şart. Uzun idle connection’larda proxy veya load balancer connection’ı kapatabiliyor. Her 20-30 saniyede bir
: heartbeatnngibi comment mesajı gönderip connection’ı canlı tutmak lazım. - Last-Event-ID. Browser reconnect olunca
Last-Event-IDheader gönderir, son aldığı event’i söyler. Server bu noktadan devam edebilir. Bu özelliği kullanırsanız client mesaj kaybı olmadan reconnect edebiliyor.
Hangisini ne zaman?
- Kullanıcı sadece veri dinleyecek: SSE.
- İki yönlü etkileşim var: WebSocket.
- Corporate firewall arkasında müşteriler var: SSE daha güvenli.
- HTTP/2 varsa: SSE rahat.
- PHP backend’de, ayrı servis açma imkanı yok: polling veya WebSocket üzerinden Pusher/Ably.
- Yüksek frekanslı binary veri: WebSocket.
Basit başlayın, gerektiğinde WebSocket’e geçin. Çoğu real-time ihtiyacı için SSE hem daha kolay hem daha ekonomik.