Skip to content

Server-Sent Events (SSE): Basit Gerçek Zamanlı Veri Akışı

Published: at 10:00 AMSuggest an edit

Gerçek zamanlı özellik geliştiren ekipler çoğu zaman doğrudan WebSocket’e yöneliyor. Oysa yalnızca sunucudan istemciye veri akışı gereken durumlarda Server-Sent Events (SSE) çok daha sade, bakım maliyeti daha düşük ve mevcut HTTP altyapısıyla daha uyumlu bir seçenek olabilir.

SSE Nedir? Problem Ne?

Web uygulamalarında real-time veri göstermek istiyorsunuz. Stock price’lar, notification’lar, live score’lar, chat mesajları… Klasik HTTP request-response modeli bunun için uygun değil çünkü client sürekli “yeni bir şey var mı?” diye sormak zorunda (polling). Bu hem verimsiz hem de real-time değil.

İşte SSE, server’ın client’a sürekli veri “push” edebilmesini sağlayan bir teknoloji. HTTP protokolü üzerinden, tek yönlü (server’dan client’a), sürekli bir veri akışı kuruyorsunuz. Client bir kere bağlanıyor, server istediği zaman veri gönderiyor.

SSE vs WebSocket vs Long Polling

Hemen karşılaştıralım çünkü bu kafa karışıklığı çok yaygın:

Long Polling: Client request atıyor, server yeni veri gelene kadar bekletiyor. Veri gelince response dönüyor, client hemen yeni request atıyor. Hack gibi bir çözüm, modern değil.

WebSocket: Full-duplex, bi-directional communication. Hem client hem server istediği zaman mesaj gönderebiliyor. Güçlü ama complex. Ayrı bir protokol (ws://), proxy/firewall sorunları olabiliyor.

SSE: Unidirectional (sadece server→client), standart HTTP üzerinden çalışıyor. Otomatik reconnection var. Browser native support var. Basit!

Ne Zaman SSE Kullanmalı?

SSE şu durumlarda iyi çalışır:

Eğer client’ın da server’a sürekli veri göndermesi gerekmiyorsa (chat uygulaması gibi), SSE genelde WebSocket’ten daha iyi seçim!

SSE’nin Teknik Detayları

SSE aslında çok basit bir protokol. Server, Content-Type: text/event-stream header’ı ile response başlatıyor ve connection’ı açık tutuyor. Sonra plain text formatında event’ler gönderiyor:

data: Hello World\n\n
data: {"user": "john", "message": "Hi!"}\n\n
event: notification\ndata: New message arrived\n\n

Format bu kadar basit! Her mesaj data: ile başlıyor, çift newline ile bitiyor. İsterseniz event: ile event type belirtebiliyorsunuz, id: ile mesaj ID’si verebiliyorsunuz.

Browser Support ve Automatic Reconnection

Modern browser’ların hepsi SSE’yi destekliyor (IE hariç tabii ki, ama kim kullanıyor ki?). En güzel özelliklerinden biri automatic reconnection. Connection koparsa, browser otomatik olarak tekrar bağlanmaya çalışıyor. Kaldığı yerden devam etmek için son event ID’sini Last-Event-ID header’ında gönderiyor.

Bu davranış pratikte önemlidir. Network kesintileri veya kısa servis yeniden başlatmalarında çoğu durumda ek reconnect kodu yazmadan akış devam eder.

HTTP/2 ve Multiplexing

SSE’nin eski bir problemi vardı: Browser’lar aynı domain’e maksimum 6 concurrent connection açabiliyordu (HTTP/1.1’de). Yani 6 SSE connection açarsanız, başka request atamazdınız.

HTTP/2 ile bu problem büyük ölçüde hafifledi. Multiplexing sayesinde aynı bağlantı üzerinde birden fazla isteği yönetmek daha kolay hale geldi ve SSE çoğu modern altyapıda rahatça kullanılabilir oldu.

Basit Örnekler

Server tarafı (Node.js/Express):

app.get("/events", (req, res) => {
  // Set headers for SSE
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
  });

  // Send initial message
  res.write("data: Connected!\n\n");

  // Send timestamp every second
  const interval = setInterval(() => {
    res.write(`data: ${new Date().toISOString()}\n\n`);
  }, 1000);

  // Clean up on client disconnect
  req.on("close", () => {
    clearInterval(interval);
  });
});

Client tarafı (JavaScript):

// Create connection
const eventSource = new EventSource("/events");

// Handle messages
eventSource.onmessage = event => {
  console.log("Received:", event.data);
};

// Handle specific event types
eventSource.addEventListener("notification", event => {
  showNotification(event.data);
});

// Handle errors
eventSource.onerror = error => {
  console.error("SSE error:", error);
};

Load Balancing ve Scaling

SSE connection’ları long-lived olduğu için load balancing’de dikkatli olmalısınız. Sticky sessions kullanmanız ya da event’leri Redis/RabbitMQ gibi bir message broker üzerinden dağıtmanız gerekebilir.

Scaling stratejileri:

Authentication ve Security

SSE normal HTTP request gibi çalıştığı için, authentication kolay:

Security için:

SSE’nin Limitasyonları

Her teknoloji gibi SSE’nin de limitasyonları var:

Unidirectional: Sadece server→client. Client veri göndermek için normal HTTP request kullanmalı.

Text only: Binary data gönderemezsiniz. Base64 encoding gerekli.

No custom headers: EventSource API custom header desteklemiyor.

Connection limits: Eski browser’larda ve HTTP/1.1’de connection limit var.

Real-World Use Cases

GitHub: Pull request’lerdeki real-time update’ler SSE ile.

Twitter: Timeline update’leri (eski versiyonda).

Grafana: Monitoring dashboard’lardaki real-time metrikler.

Stock trading platforms: Price update’leri.

CI/CD tools: Build progress ve log streaming.

SSE vs WebSocket: Hangisini Seçmeli?

SSE seçin eğer:

WebSocket seçin eğer:

Modern Alternatifler

WebTransport: WebSocket’in halefi gibi. QUIC protokolü üzerinde, daha hızlı.

gRPC-Web: gRPC’nin browser versiyonu. Streaming desteği var.

GraphQL Subscriptions: GraphQL üzerinden real-time data.

Ama çoğu use case için SSE hala en basit ve yeterli çözüm!

Performance Tips

Compression kullanın: Text data olduğu için gzip çok etkili.

Heartbeat gönderin: Connection’ın alive olduğundan emin olmak için.

Batch update’ler: Her küçük değişiklik için ayrı event göndermek yerine batch’leyin.

Event ID kullanın: Reconnection sonrası kaldığı yerden devam için.

Memory leak’lere dikkat: Disconnect olan client’ları temizlemeyi unutmayın!

Sonuç

SSE, her gerçek zamanlı problem için tek cevap değil; ama tek yönlü veri akışı gereken birçok senaryoda gereksiz karmaşıklığı azaltır. Özellikle bildirim, ilerleme durumu ve canlı panel gibi use case’lerde WebSocket’e göre daha okunabilir ve daha hızlı devreye alınan bir çözüm sunar.

Kısa öneri şu: önce veri yönünü ve bağlantı modelini netleştirin. İstemciden sunucuya sürekli mesaj gerekmiyorsa, ilk değerlendirilmesi gereken seçeneklerden biri SSE olmalı.

Kaynaklar



Previous Post
Functional Programming: Kod Yazmanın Matematiksel Sanatı
Next Post
SCP: Güvenli Dosya Transferinin Klasiği