11 puan yazan GN⁺ 2025-04-13 | 3 yorum | WhatsApp'ta paylaş
  • WebSocket gerçek zamanlı iletişim için yararlıdır, ancak her zaman gerekli değildir; HTTP tabanlı alternatifler daha basit ve daha kararlı olabilir
  • İşlem yönetimi, bağlantı yönetimi ve sunucu karmaşıklığı açısından WebSocket gereğinden fazla ek yük yaratabilir
  • HTTP Streaming ve eventkit kütüphanesi kullanılarak WebSocket olmadan da gerçek zamanlı senkronizasyon ve olay işleme mümkün olabilir

WebSocket nedir

  • WebSocket, istemci ile sunucu arasında kalıcı çift yönlü bir iletişim kanalı açan bir teknolojidir
  • Bağlantı HTTP üzerinden başlatılır, ancak sonrasında iletişim ayrı bir protokol üzerinden gerçekleşir
  • Gerçek zamanlı uygulamalar geliştirmede sık kullanılır ve çift yönlü iletişim sağlayabildiği için faydalıdır

WebSocket mesajları işlemsel değildir

  • WebSocket, istek ile yanıt arasında doğrudan bir ilişkiyi garanti etmez
  • Durum değiştirme komutları ile bunların sonuç mesajları aynı akış içinde karışık şekilde gelebilir
  • Örneğin bir istemci durumu değiştirip hata alsa bile, bu hatanın hangi komuta ait olduğunu anlamak zor olabilir
  • Çözüm olarak komut ile yanıtı bağlamak için requestId eklenebilir, ancak bu da karmaşıklığı ve yönetim maliyetini artırır
  • Komutları HTTP kullanan işlemsel bir yöntemle gönderip, WebSocket’i yalnızca durum değişikliklerini yayınlamak için kullanmak daha basittir
  • Gönderim tarafı HTTP isteğiyle, alım tarafı ise WebSocket veya başka bir streaming yöntemiyle ayrılabilir

WebSocket bağlantı yaşam döngüsünü yönetmenin zorlukları

  • WebSocket kullanıldığında bağlantının başlatılması, sonlandırılması, hata durumu ve yeniden bağlanma gibi konuların doğrudan ele alınması gerekir
  • Tarayıcıdaki temel işleyiş örnekleri; bağlantının açılması, mesaj alınması, hata oluşması ve bağlantının kapanması olaylarının işlenmesini içerir
  • Yeniden bağlanma mantığı, mesaj arabelleğe alma ve exponential backoff gibi ek mantık gerekir
  • Buna karşılık HTTP’de her isteğin başlangıcı ve sonu nettir, bu da uygulamayı basitleştirir
  • Karmaşık yaşam döngüsü yönetimi, ancak WebSocket kullanmak için güçlü bir gerekçe olduğunda haklı çıkarılabilir

Sunucu kodunda artan karmaşıklık

  • WebSocket, HTTP upgrade isteklerini işlemek zorundadır; bu da ek handshake mantığı gerektirir
  • Sec-WebSocket-Key gibi özel header’ların doğrulanması ve uygun yanıt header’larının döndürülmesi gerekir
  • WebSocket bağlantısı kurulduktan sonra mesaj alma ve gönderme durumunu sürekli korumak gerekir; parçalı frame işleme gibi sorunlar da ortaya çıkabilir
  • Yalnızca HTTP kullanmaya kıyasla debug etme ve hata işleme daha zordur
  • Framework’ler bazı süreçleri soyutlasa da temel karmaşıklık ortadan kalkmaz

Alternatif: HTTP Streaming

  • HTTP, doğası gereği streaming destekleyen bir protokoldür; tüm dosyayı değil, veri akışını gerçek zamanlı olarak iletebilir
  • Mevcut WebSocket’in yalnızca alım tarafındaki işlevi HTTP streaming ile değiştirilebilir
  • Asenkron generator’lar kullanılarak durum güncellemeleri akış biçiminde işlenebilir
  • Sunucu tarafı akışı
    • Durum güncellemeleri komut işleme işlevinde yapılır
    • Bağlı istemciler, generator aracılığıyla her yeni değer geldiğinde bunu alır
    • Durum değiştirme komutları HTTP POST ile gönderilir, gerçek zamanlı akış ise GET isteğiyle abone olunarak alınır
  • İstemci tarafı akışı
    • Fetch API ve Stream Reader üzerinden gerçek zamanlı veri alınır
    • Metin decode edildikten sonra UI güncellenir
  • Bu yapıyla WebSocket olmadan da gerçek zamanlı durum senkronizasyonu uygulanabilir

Bonus: eventkit kütüphanesine kısa bir giriş

  • eventkit, asenkron akışları kolayca kurup gözlemlemeyi sağlayan bir kütüphanedir
  • RxJS’e benzer, ancak yan etki yönetimi iyileştirilmiştir ve generator tabanlı tasarlanmıştır
  • Durum güncellemeleri akışa push edildiğinde, istemci bunları gerçek zamanlı olarak alabilir
  • Stream ve AsyncObservable ile hem sunucu hem istemci tarafında basit uygulamalar kurulabilir
  • Sunucu tarafında eventkit kullanımı
    • Durum değişiklikleri Stream’e push edilir ve istemciler bu akışa abone olur
  • İstemci tarafında eventkit kullanımı
    • Akış verisi alınır, decode edilir ve ardından UI güncellenir
  • Resmî GitHub deposu ve HTTP Streaming rehberi de sunulmaktadır

GitHub: https://github.com/hntrl/eventkit

3 yorum

 
[Bu yorum gizlendi.]
 
[Bu yorum gizlendi.]
 
GN⁺ 2025-04-13
Hacker News görüşleri
  • HTTP streaming’in bu kullanım kalıbı düşünülerek tasarlandığını sanmıyorum. HTTP streaming, büyük veriyi parçalara bölmek içindir. Streaming’i bir pub/sub mekanizması gibi kullanırsanız pişman olabilirsiniz. HTTP aracılar bu trafik kalıbını beklemez (NGINX, CloudFlare vb.). WiFi bağlantısı her koptuğunda fetch API muhtemelen isteği başarısız sayıp hata üretecektir

    • Çoğu durumda WebSockets gerekmez. Server-Sent Events (SSE) daha basit bir çözümdür. SSE’nin ilgi görmemiş olması üzücü
  • İstek/yanıt döngüsü elde etmek için sunucuya RequestID göndermek garip ya da aşırı bir şey değil. Ciddi uygulamalarda send(message).then(res => ...) gibi bir API’ye sahip olmak her zaman değerlidir

    • Upgrade isteği kafa karıştırıcı. WebSocket sunucusunun HTTP sunucusunun içine gömülü ve onunla entegre olmaması can sıkıcı
    • WebSocket isteğinde headers['authorization'] okuyan middleware’i yeniden kullanmak yerine, istek başlığıymış gibi davranan connectionParams nesnesine erişmek gerekiyor
    • WebSocket tarayıcı API’si, EventSource’dan daha rahat kullanılıyor
  • Video streaming’de istemci chunk’ları range ile ister; bu tek bir HTTP bağlantısı değildir

  • EventKit yerine SSE kullanmak daha iyi

  • POC’de geleneksel HTTP form gönderimini kullanacağım. Başka bir şeye gerek yok

    • Mimar, WebSocket gerektiğini iddia ediyor
    • POC için XHR ya da WebSocket gerekmiyor. Bu sıralı bir satın alma akışı
    • Sonunda gereksiz bir WebSocket sunmuş oluyoruz
  • HTTP2 ile ilgili sorun, server push’ın mevcut protokolün üstüne eklenmiş olması. HTTP bir kaynak aktarım protokolüdür ve gereksiz ek yük getirir. HTTP2’nin ana amacı, sunucunun dosyaları/kaynakları istemciye önceden iterek gidiş-dönüş gecikmesini azaltmasıdır

    • WebSockets, çift yönlü iletişim için tasarlanmış daha basit bir protokoldür. Tek bağlantıyla veri akışını kontrol etmek daha kolaydır. Durum yönetimi ve bağlantı kaybından kurtarma daha kolaydır. Kimlik doğrulama ve erişim kontrolü basitleşir
  • WebSockets akış olarak değil, datagram (paket) olarak gönderir. JavaScript kütüphanelerindeki WebSockets API’si backpressure’ı yönetemez ve tüm hataları ele alamaz. Onu TCP stream gibi kullanacaksanız dikkatli olmanız gerekir

  • WebSockets’i production’a aldıktan sonra pişman oldum. NGINX’in 4/8 saat sonra bağlantıyı kapatması, tarayıcının uykudan sonra yeniden bağlanmaması gibi sorunlar vardı. Mümkünse WebSockets’ten ve uzun süreli bağlantılardan kaçınmak gerekir

  • WebSockets hakkında idealize edilmiş bir algı var. Streaming/gerçek zamanlı kullanım senaryolarında WebSockets kullanma eğilimi bulunuyor. WebSockets, HTTP araçlarının sadeliğini ve avantajlarını kaybettiriyor. Streaming sunucu değişiklikleri için çözüm h2/h3 ve SSE’dir. İstemci başına en fazla 0.5 req/s olacak şekilde batch edebiliyorsanız WebSockets’e ihtiyacınız yok

  • HTTP streaming ile ilgilenenler Braid-HTTP’ye bakmalı. HTTP’yi event streaming için zarif biçimde genişleterek güçlü bir durum senkronizasyon protokolü sunuyor