- Gerçek zamanlı web uygulamalarında sunucu-istemci olay iletimi için Long Polling, WebSockets, SSE, WebRTC, WebTransport seçeneklerinden hangisinin seçildiği; gecikmeyi, çift yönlülüğü, uygulama zorluğunu ve operasyonel kısıtları büyük ölçüde değiştirir
- WebSockets, tek bir uzun ömürlü bağlantı üzerinden çift yönlü iletişim sağlar; ancak gerçek işletimde bağlantı kaybını algılama, yeniden bağlanma ve ping-pong heartbeat nedeniyle çoğu zaman Socket.IO gibi kütüphanelerle birlikte kullanılır
- Server-Sent Events, HTTP tabanlı, sunucudan istemciye tek yönlü bir akış olduğu için uygulaması ve yeniden bağlanma yönetimi basittir; ancak temel EventSource API’sinde POST gövdesi veya özel header gönderimi konusunda kısıtlar vardır
- WebTransport, HTTP/3 QUIC tabanlı çoklu akışları ve güvenilir/güvenilir olmayan aktarımı destekler; ancak Mart 2024 itibarıyla Working Draft durumundadır ve Safari ile Node.js’te yerel destek olmadığı için henüz genel amaçlı bir seçenek olarak görmek zordur
- Mobil arka plan sonlandırması, alan adı başına bağlantı sayısı sınırları, kurumsal proxy’ler ve güvenlik duvarları, yeniden bağlanma sırasında olay kaçırma gibi nedenlerle gerçek uygulamalarda senkronizasyon kurtarma mantığı ve altyapı testleri de gerekir
Gerçek zamanlı sunucu-istemci iletişim teknolojilerinin gelişimi
- Gerçek zamanlı web uygulamalarında sunucunun istemciye olay göndermesi temel gereksinimlerden biri hâline gelir
- Başlangıçta HTTP üzerinde çalışan Long Polling, tarayıcılarda mümkün olan bir sunucu-istemci mesajlaşma yöntemi olarak kullanılıyordu
- Daha sonra WebSockets, çift yönlü iletişim için daha sağlam bir yöntem olarak ortaya çıktı
- Server-Sent Events(SSE), yalnızca sunucudan istemciye gönderim yapan tek yönlü iletişimi daha basit şekilde sunar
- WebTransport daha verimli, esnek ve ölçeklenebilir bir yöntem olma potansiyeline sahiptir; ancak şu anda destek kapsamı sınırlıdır
- WebRTC, bazı niş sunucu-istemci olay kullanım senaryoları için düşünülebilir; ancak amacı farklı olduğu için ana seçenekler arasında ele alınması uygun değildir
Long Polling
- Long Polling, normal XHR istekleriyle sunucu push iletişimini taklit eden bir yöntemdir
- İstemci sunucuya bir istek açtığında, sunucu yeni veri oluşana kadar yanıtı bekletir
- Yeni bilgiyi gönderdikten sonra bağlantı kapanır ve istemci hemen bir sonraki isteği yeniden başlatır
- Geleneksel periyodik polling’e göre güncellemeler daha hızlıdır; gereksiz ağ trafiğini ve sunucu yükünü azaltabilir
- Ancak WebSockets gibi gerçek zamanlı teknolojilere göre verimliliği daha düşüktür ve veri aktarım zamanlamasına bağlı olarak gecikme oluşabilir
- İstemci tarafı uygulaması basittir; ancak backend’de yeniden bağlanmakta olan istemcilerin olayları kaçırmamasını garanti etmek zordur
WebSockets
- WebSockets, istemci ile sunucu arasında tek bir uzun ömürlü bağlantı oluşturur ve full-duplex iletişim sağlar
- Bağlantı kurulduktan sonra iki taraf da HTTP istek-yanıt döngüsünün overhead’i olmadan bağımsız olarak veri gönderebilir
- Gerçek zamanlı sohbet, oyun, finansal işlem platformları gibi düşük gecikme ve sık güncelleme gerektiren uygulamalar için uygundur
- Temel WebSocket API’sini kullanmak kolaydır; ancak production’da bağlantı kaybı ve yeniden oluşturma süreçleri karmaşıklaşır
- Bağlantının hâlâ kullanılabilir olup olmadığını algılamak zor olduğu için genellikle ping-and-pong heartbeat eklenir
- Bu karmaşıklık nedeniyle çoğu durumda Socket.IO gibi kütüphaneler kullanılır; Socket.IO gerektiğinde Long Polling fallback’i de sağlar
Server-Sent Events
- Server-Sent Events(SSE), HTTP üzerinde sunucu güncellemelerini istemciye push etmek için kullanılan standart yöntemdir
- WebSockets’ten farklı olarak yalnızca sunucu→istemci tek yönlü iletişim için tasarlanmıştır
- Canlı haber akışları, spor skorları, gerçek zamanlı güncellemeler gibi istemcinin sunucuya mesaj göndermesinin gerekmediği durumlar için uygundur
- SSE, tek bir HTTP isteğinde bağlantıyı açık tutarken backend’in her olay oluştuğunda yanıtı satır satır akıtması olarak düşünülebilir
- Tarayıcı istemcisinde olay akışını almak için bir EventSource instance’ı başlatılır
- EventSource, WebSockets’ten farklı olarak bağlantı koptuğunda otomatik yeniden bağlanır
- Sunucu
Content-Typeheader’ınıtext/event-streamolarak ayarlamalı ve olay tipi, veri payload’u, olay ID’si, retry timing gibi alanları SSE specification ile uyumlu biçimde formatlamalıdır
WebTransport
- WebTransport, web istemcileri ile sunucular arasında verimli ve düşük gecikmeli iletişim için bir API’dir
- HTTP/3 QUIC protocol kullanarak birden fazla akışta veri gönderebilir
- Güvenilir aktarımı, güvenilir olmayan aktarımı ve sırasız veri aktarımını birlikte destekler
- Gerçek zamanlı oyunlar, canlı yayın, işbirliği platformları gibi yüksek performanslı networking gerektiren uygulamalar için güçlü bir araç olabilir
- Mart 2024 itibarıyla WebTransport Working Draft durumundadır ve geniş destek görmemektedir
- Safari browser içinde henüz kullanılamaz ve Node.js için de yerel destek yoktur
- Destek yaygınlaşsa bile API çok karmaşık olduğundan, doğrudan uygulama kodunda kullanılmaktan çok WebTransport üzerinde kütüphane geliştirilmesi daha olasıdır
WebRTC
- WebRTC, tarayıcılar ve mobil uygulamalar içinde eklenti olmadan gerçek zamanlı iletişim özellikleri sağlayan açık kaynaklı bir proje ve API standardıdır
- Tarayıcılar arasında ses, video ve veri değişimi için peer-to-peer bağlantıları destekler
- NAT ve güvenlik duvarlarını aşmak için ICE, STUN, TURN gibi protokoller kullanır
- WebRTC, istemci-istemci etkileşimi için oluşturulmuştur; ancak sunucunun istemci gibi davranması sağlanarak sunucu-istemci iletişiminde de kullanılabilir
- Bu yaklaşım yalnızca niş kullanım senaryolarına uygun olduğu için ana seçenek karşılaştırmasının dışında bırakılır
- WebRTC’nin çalışması için zaten bir signaling sunucusu gerekir ve bu sunucu WebSockets, SSE veya WebTransport seçeneklerinden biri üzerinde çalışır
- Bu nedenle WebRTC’yi bu teknolojilerin doğrudan alternatifi olarak kullanma amacı zayıflar
Teknolojiye göre başlıca kısıtlar
-
Çift yönlü veri aktarımı
- Aynı bağlantı üzerinde sunucu verisi alıp istemci verisi göndermeyi yalnızca WebSockets ve WebTransport destekler
- Long Polling teorik olarak mümkün olsa da mevcut long-polling bağlantısına yeni veri göndermek için ek HTTP isteği gerektiğinden önerilmez
- Long Polling’de mevcut bağlantıyı bozmadan istemci→sunucu verisini ayrı bir HTTP isteğiyle göndermek daha iyidir
- SSE, sunucuya ek veri gönderme özelliğini desteklemez
- Temel yerel EventSource API, ilk istekte bile HTTP body içinde POST gibi veriler gönderemez
- Veriyi URL parametrelerine koymak gerekir; ancak credentials sunucu log’larına, proxy’lere ve cache’lere sızabileceği için güvenlik açısından iyi değildir
- RxDB bu sorundan kaçınmak için yerel
EventSource APIyerine eventsource polyfill kullanır; bu kütüphane özel HTTP header gibi özellikler ekler - Microsoft’un fetch-event-source kütüphanesi body verisi göndermeye ve
GETyerinePOSTisteği kullanmaya izin verir
-
Alan adı başına bağlantı sayısı sınırı
- Çoğu modern tarayıcı alan adı başına 6 bağlantıya izin verir; bu sınır, güvenilir sunucu→istemci mesajlaşma yöntemlerinin genel kullanılabilirliğini kısıtlar
- 6 bağlantı sınırı tarayıcı sekmeleri arasında da paylaşılır; bu yüzden aynı sayfa birden fazla sekmede açıldığında sekmeler aynı bağlantı havuzunu paylaşmak zorundadır
- HTTP/1.1 RFC, sunucu veya proxy başına daha düşük bir sayı olan 2 bağlantı önerir
- Bu politika, ziyaretçileri kullanarak DDoS yapılmasını engellemek açısından makuldür; ancak meşru sunucu-istemci iletişiminde birden fazla bağlantı gerektiğinde sorun yaratabilir
- Bunu aşmak için HTTP/2 veya HTTP/3 kullanarak tarayıcının alan adı başına yalnızca tek bağlantı açmasını ve veriyi multiplexing ile işlemesini sağlamak gerekir
- HTTP/2 ve HTTP/3’te de SETTINGS_MAX_CONCURRENT_STREAMS ayarı gerçek eşzamanlı akış sayısını sınırlar; çoğu yapılandırmada varsayılan değer 100 concurrent streams’tir
- EventSource gibi belirli API’ler için tarayıcı bağlantı sınırını artırabilir; ancak Chromium ve Firefox ile ilgili issue’lar “won’t fix” olarak işaretlenmiştir
-
Tarayıcı uygulamalarında bağlantı sayısını azaltma
- Tarayıcı uygulamalarında kullanıcının uygulamayı aynı anda birden fazla sekmede açabileceği varsayılmalıdır
- Varsayılan olarak her sekme bir sunucu stream bağlantısı açabilir; ancak çoğu zaman bu gereksizdir
- Birden fazla sekme açık olsa da yalnızca tek bir bağlantı açıp bunu sekmeler arasında paylaşmak mümkündür
- RxDB, sunucu ile istemci arasındaki replication stream’i tek tutmak için broadcast-channel npm package içindeki LeaderElection özelliğini kullanır
- Bu paket, RxDB olmadan da başka uygulamalarda tek başına kullanılabilir
Mobil, proxy ve güvenlik duvarlarının operasyonel kısıtları
- Android ve iOS gibi mobil işletim sistemlerinde WebSockets dahil açık bağlantıları sürekli korumak zordur
- Mobil OS, belirli bir süre hareketsizlikten sonra uygulamayı arka plana alabilir ve açık bağlantıları kapatabilir
- Bu davranış, pil tasarrufu ve performans optimizasyonu için kaynak yönetimi stratejisinin bir parçasıdır
- Geliştiriciler, sunucunun istemciye veri göndermesi gerektiğinde kalıcı bağlantılar yerine çoğu zaman mobil push bildirimleri kullanır
- Push bildirimleri, sürekli açık bir bağlantı olmadan sunucunun yeni veriyi uygulamaya bildirmesini ve uygulama davranışını veya güncellemeleri tetiklemesini sağlar
- Kurumsal ortamlarda proxy’ler ve güvenlik duvarları HTTP dışı bağlantıları engelleyerek WebSocket sunucusunu altyapıya eklemeyi zorlaştırabilir
- Bu ortamlarda HTTP tabanlı SSE, kurumsal entegrasyon için daha kolay bir yöntem olabilir
- Long Polling de yalnızca normal HTTP isteklerini kullandığı için bir seçenek olabilir
Performans karşılaştırması
- WebSockets, SSE, Long Polling ve WebTransport karşılaştırılırken gecikme, throughput, sunucu yükü ve ölçeklenebilirlik birlikte değerlendirilmelidir
- Go sunucu implementasyonunda mesaj sürelerini test eden realtime-web repo, WebSockets, WebRTC ve WebTransport performansının benzer olduğunu gösterir
- WebTransport, HTTP/3 tabanlı yeni bir teknoloji olduğu için Mart 2024 sonrasında daha fazla performans optimizasyonu ortaya çıkabilir
- WebTransport güç kullanımını azaltacak şekilde optimize edilmiştir; ancak bu metrik test edilmemiştir
-
Gecikme
- WebSockets, tek bir kalıcı bağlantı üzerindeki full-duplex iletişim nedeniyle en düşük gecikmeyi sağlar
- SSE de sunucu→istemci iletişiminde düşük gecikme sunar; ancak istemcinin sunucuya mesaj göndermesi için ek HTTP isteği gerekir
- Long Polling, her veri aktarımında yeni HTTP bağlantısı oluşturduğu için daha yüksek gecikmeye sahiptir
- Long Polling’de, sunucunun olay göndermek istediği anda istemci yeni bağlantı açıyorsa gecikme büyük ölçüde artabilir
- WebTransport’un WebSockets’e benzer düşük gecikme sağlaması beklenir ve HTTP/3’ün daha verimli multiplexing ve congestion control özelliklerinden yararlanır
-
Throughput
- WebSockets, kalıcı bağlantı sayesinde yüksek throughput sağlayabilir; ancak istemcinin sunucu gönderim hızı kadar hızlı işleyemediği backpressure sorunu throughput’u etkileyebilir
- SSE, WebSockets’e göre daha az overhead’e sahip olduğu için tek yönlü sunucu→istemci broadcast’lerinde potansiyel olarak daha yüksek throughput sağlayabilir
- Long Polling, bağlantıları sık açıp kapatma overhead’i nedeniyle genellikle daha düşük throughput’a sahiptir ve daha fazla sunucu kaynağı tüketir
- WebTransport’un tek bağlantı içinde hem tek yönlü hem çift yönlü akışlarda yüksek throughput desteklemesi beklenir ve birden fazla akış gerektiren senaryolarda WebSockets’i aşabilir
-
Ölçeklenebilirlik ve sunucu yükü
- WebSockets, çok sayıda bağlantı açık tutuldukça sunucu yükünü ciddi şekilde artırabilir; bu da kullanıcı sayısı yüksek uygulamaların ölçeklenebilirliğini etkileyebilir
- SSE, çoğunlukla sunucu→istemci güncellemeleri gereken senaryolarda daha iyi ölçeklenebilir
- SSE, protocol upgrade gibi WebSocket prosedürleri olmadan normal HTTP istekleri kullandığı için bağlantı overhead’i daha düşüktür
- Long Polling, sık bağlantı kurulumu nedeniyle sunucu yükünü artırır; en düşük ölçeklenebilirliğe sahiptir ve yalnızca fallback mekanizması olarak uygundur
- WebTransport, HTTP/3’ün bağlantı ve akış işleme verimliliğine dayanarak yüksek ölçeklenebilirlik hedefiyle tasarlanmıştır ve WebSockets ile SSE’ye göre sunucu yükünü azaltma potansiyeline sahiptir
Kullanım senaryosuna göre öneriler
- SSE, uygulaması en anlaşılır seçenektir; mevcut HTTP/S protokollerini kullanarak kurumsal güvenlik duvarı kısıtlarını ve diğer protokollerde ortaya çıkabilecek teknik sorunları aşmayı kolaylaştırır
- Node.js ve diğer sunucu framework’lerine kolayca entegre edilebilir
- Haber akışları, hisse senedi fiyatları, canlı etkinlik streaming’i gibi sık sunucu→istemci güncellemesi gereken uygulamalar için uygundur
- WebSockets, sürekli çift yönlü iletişim gereken senaryolarda güçlüdür
- Tarayıcı oyunları, sohbet uygulamaları, canlı spor güncellemeleri gibi sürekli etkileşim gerektiren durumlarda ana seçenek hâline gelir
- WebTransport potansiyele sahip olsa da sunucu framework desteği geniş değildir ve Node.js ile Safari uyumluluğu eksiktir
- WebTransport HTTP/3’e dayanır; nginx gibi birçok web sunucusunda HTTP/3 desteği hâlâ experimental durumundadır
- Hem güvenilir hem güvenilir olmayan veri aktarımını destekleyen geleceğe dönük bir teknolojidir; ancak mevcut kullanım senaryolarının çoğu için henüz uygulanabilir bir seçenek değildir
- Long Polling, tekrar tekrar yeni HTTP bağlantısı kurmanın verimsizliği ve yüksek overhead’i nedeniyle genellikle eski bir yöntemdir
- WebSockets veya SSE desteklemeyen ortamlarda fallback olarak kullanılabilir; ancak performans kısıtları nedeniyle genel kullanım için önerilmez
Yeniden bağlanma sırasında olay kaçırma sorunu
- Herhangi bir gerçek zamanlı streaming teknolojisi üzerinde özellik geliştirirken bağlantı kopması ve yeniden bağlanma durumları dikkate alınmalıdır
- İstemci bağlanma aşamasındaysa, yeniden bağlanıyorsa veya offline ise sunucuda oluşan olayları stream üzerinden alamayabilir
- Sunucu, hisse senedi fiyatları gibi her seferinde içeriğin tamamını stream ediyorsa kaçan olaylar önemli olmayabilir
- Backend yalnızca kısmi sonuçlar stream ediyorsa kaçan olaylar mutlaka ele alınmalıdır
- Backend’in istemci başına hangi olayların başarıyla iletildiğini hatırlaması ölçeklenebilir değildir
- Bu sorunu istemci tarafı mantıkla ele almak daha iyidir
- RxDB Sync Engine iki çalışma modu kullanır
- checkpoint iteration mode: Normal HTTP istekleriyle backend verilerini tekrar tekrar sorgular ve istemci yeniden senkronize olana kadar arayı kapatır
- event observation mode: Gerçek zamanlı stream güncellemeleriyle istemciyi senkron durumda tutar
- İstemci bağlantısı koparsa veya hata oluşursa replication kısa süreliğine checkpoint iteration mode’a geçerek yeniden sunucuyla aynı duruma gelene kadar senkronize olur
- Bu yöntem kaçan olayları telafi eder ve istemcinin her zaman sunucuyla tam olarak aynı duruma senkronize olmasını sağlar
Kurumsal altyapıda kontrol edilmesi gerekenler
- Kurumsal altyapıda streaming teknolojilerinin genelinde sorunlar ortaya çıkabilir
- Proxy’ler ve güvenlik duvarları trafiği engelleyebilir veya istek/yanıtları istemeden bozabilir
- Bu tür ortamlarda gerçek zamanlı uygulama geliştirirken, seçilen teknolojinin ilgili altyapıda çalışıp çalışmadığı önce test edilmelidir
1 yorum
Hacker News yorumları
Server-Sent Events’e hep sıcak bakmışımdır. Basit; kullanması ve uygulaması kolay.
WebSocket, kullanım belli bir seviyeyi aşınca ölçeklendirmesi epey karmaşıklaşır.
https://crbug.com/275955
Neden bunu doğrudan multipart streaming response olarak yapmadıklarını merak ediyorum. Metadata’yı da destekliyor ve çok yaygın uygulanmış bir format zaten.
Ayrıca bilinmesi gereken bazı dezavantajlar var.
WebSocket’te akış kontrolü (backpressure) ve çoklama yok; gerekiyorsa kendiniz yapmanız ya da RSocket gibi bir şey kullanmanız gerekir. SSE de ikili veriyi doğrudan gönderemez, base64 gibi bir kodlama gerekir.
WebTransport bu sorunları ele alıyor ve HOL blocking’i de çözüyor; ama Python 2→3 ya da IPv6 geçişinde olduğu gibi insanların eski sürümleri kullanmaya devam etmesinden ve yükseltme faydasının küçük algılanmasından endişeleniyorum.
Tarayıcı TCP ile çalışmaya devam ettiği sürece bazı ağlar UDP’yi, dolayısıyla HTTP/3/WebTransport’u tamamen engelleyebilir.
WebTransport’a geçişin yavaş olabileceği endişesi, zamanında TLS aktarımı, HTTP/3 ve XHR için de aynı şekilde söylenebilecek bir şeydi. Birkaç büyük tarayıcı motorunun hâkim olduğu yapı nedeniyle yeni tarayıcı özelliklerinin ve protokollerin dağıtımı görece kolay.
TCP mümkün diye bazı ağların UDP’yi engelleyeceği mantığı, HTTP 1.1 TLS’siz mümkün diye HTTP/2 ve TLS’nin de sürekli engelleneceğini söylemeye benziyor. Tamamen yanlış değil, ama HTTP/2’nin ve özellikle TLS’nin geniş benimsenmesine bakınca sanıldığı kadar büyük bir sorun değil gibi.
Küçük ofislerde ya da filmlerde görülebilecek distopik kurumsal ortamlarda kapatılabilir; ama bazı ağların UDP’yi yasaklayabilmesinin neden bu kadar önemli olduğunu anlamıyorum. Bazı ağlar google.com’u ya da wikipedia.com’u da engelliyor, ama bu o hizmetlerin başarısız olduğu anlamına gelmiyor.
Yazıdaki WebRTC açıklaması doğru değil. İstemci/sunucu WebRTC, ayrı bir “sinyalleme sunucusu” olmadan da mümkündür; sunucu sinyallemeyi yapabilir.
Yalnızca birkaç ek gidiş dönüş gerekir, ayrı bir sunucu gerekmez. WebRTC data channel, WebSocket veya SSE yerine oldukça iyi çalışır; özellikle HOL blocking’den kaçınmak istediğinizde iyidir. Pion veya str0m gibi işin neredeyse tamamını yapan çok sayıda kütüphane de var.
WebTransport API’sinin karmaşık olduğu sözü de abartılı görünüyor. Gelişmiş özelliklere ihtiyacınız yoksa onları yok sayabilirsiniz; WebSocket gibi kullanmak istiyorsanız tek bir çift yönlü stream açmanız neredeyse yeterli. HOL blocking’den kaçınmak için her mesaj için bir stream açarsınız. Biraz daha karmaşık, ama mutlaka kütüphane gerektirecek seviyede değil; GitHub Copilot’ın kodu da yazması gayet olası. Ancak WebTransport hâlâ olgunlaşma aşamasında olduğu için sunucu kütüphanesi çok değil ve Safari desteği de hâlâ bekleniyor.
Genelde sinyalleme sunucusu WebSocket ile uygulanır. Mevcut istemcilerin merkeziyetsiz bootstrap’ini önermiyorsanız bunu WebRTC’nin kendisiyle uygulayamazsınız.
Geleneksel “enterprise” ve “güvenlik” IT altyapısına sahip müşteriler için geliştiriyorsanız, yenile düğmesi ekleyip geçmek daha iyi.
Bu tür ortamlarda deneyimime göre sürekli başarısız olan ve bitmek bilmeyen prosedürler yüzünden düzeltilemeyen şey, tam da bu müşteriler için gerçek zamanlı özellikler geliştirmeye çalışmaktı.
WebSocket ve SSE, ölçek büyüdükçe yönetilmesi büyük bir baş ağrısına dönüşür. Özellikle backend tarafında ayrı bir gözlemlenebilirlik gerekir; mobil cihazlarda çok dikkatli uygulanmazsa frontend hata ayıklaması kâbusa döner
Cihazlar pil tasarrufu için ağı kapatır ya da yavaşlatır; özel API’lerle açıkça I/O yapmıyorsanız bu daha da belirgin olur
Yeni bağlantı oluşturmak maliyetli bir işlemdir ve sunucunun durumu bir yerde saklaması gerekir. Bu durum saklama katmanında sorun çıkarsa istemci sürekli yeniden dener, zaman aşımına düşer ve maliyetli bir işleme sonsuza kadar takılı kalır. Veritabanına yavaş yavaş yük bindirirken iş hacmini kolayca kontrol etmenin bir yolu da değildir
Güvenilirlik açısından deneyimlerime göre long polling en iyisiydi. Olay tabanlı akış gerçekten önemli olsa bile, frontend’in 1. katman backend’e long polling yapması, bu 1. katmanın da 2. katman backend’e WebSocket ile abone olduğu iki katmanlı yapı daha iyidir; güvenilirlik kontrolü çok daha iyi hale gelir
SSE otomatik yeniden bağlanmayı destekler ve son görülen ID’yi de içererek sunucunun kesintisiz devam ettirebilmesini sağlar
Yazıda yok ama short polling de ilgili. Sunucudan istemciye mesaj gönderen bir yöntem değil, ancak paylaşımlı hosting gibi başka seçenek olmadığında hâlâ kullanışlıdır
Deneyimlerime göre polling aralığı uzun olsa bile, örneğin 20 saniye, her yanıta mesaj listesini de eklerseniz gayet iyi çalışır. Kullanıcı bir düğmeye bastığında istemci sunucuya istek gönderir; sunucu da veriyle birlikte en güncel mesaj listesini döndürür ve istemci güncel duruma gelir
WebSocket ve SSE’nin ilk istekte Authorization gibi header’ların gönderilmesini neden hâlâ desteklemediğini anlamıyorum. Gerçek zamanlı servis kimlik doğrulamasını tamamen uygulayıcıya bırakıyorlar
Spesifikasyonda iyi bir yöntem olabilir ama o kadar farklı yaklaşım gördüm ki artık fiilen yok denebilir
Sadece custom header işlemeyi değil, tüm istek metodlarını (POST, PATCH vb.), istek gövdesi eklemeyi, adlandırılmış event’lere abone olmayı ve başlangıç last event ID’si ayarlamayı da destekliyor. Async iterator olarak da kullanılabiliyor
Server-Sent Events’in basitliğini seviyorum ama
EventSourceAPI’si aceleyle uygulanıp öylece kalmış gibi görünüyor[1]: https://github.com/eventsource/eventsource
Safça bir düşünce olabilir ama HTTP/2 ve üzeri varsayıldığında, EventSource ile mesaj göndermek için
fetch()kombinasyonu, tek TCP bağlantısı kullanan diğer protokoller kadar iyi görünüyor. HTTP/3 UDP kullandığı için daha da iyiVarsayım, bağlantıyı yalnızca sekme foreground’dayken açık tutmanın gerekli olduğu. Bu yöntemi gerçekten denediğinizde ne tür sorunlar yaşandığını merak ediyorum
https://www.npmjs.com/package/@microsoft/fetch-event-source
Tamamen farklı bir şey yapmak yerine, gecikmeyi, bellek kullanımını ve CPU kaynaklarını daha da düşürerek SSE’yi daha ileri itmek mümkün mü diye merak etmiştim
Böyle yazıları görünce biraz eğleniyorum. 90’ların sonunda bir çevrim içi açık artırma sistemi tasarlamıştım; XHR istekleri hiç yoktu
Gerçek zamanlı güncellemelerin tamamını server-push/HTTP streaming ile işliyorduk. O zamanlar tüm açık bağlantılarla uğraşmak kolay değildi ama uygun bir mimari varsa kabul edilebilir ölçeğe kadar mümkündü
HTTP/2 veya HTTP/3’ün avantajları harika, ancak fiilen her yerde desteklenen HTTP 1.1’de de nelerden yararlanılabileceğini bilmek gerekiyor
Uzun polling’i biraz özlüyorum. Modern teknolojilerle kıyaslayınca gerçekten basitti. WebRTC’nin en iyisi olduğunu düşünen biri olarak bile böyle hissediyorum
Bunun yerine tekrar veri bekleyip aynı stream üzerinden ek yanıt gönderiyor
Second Life’ın ağ iletişimi, “event channel” için uzun polling HTTPS kullanıyor ve sunucu bu kanal üzerinden istemciye event mesajları gönderiyor. Mesajların çoğu UDP ile gidiyor, ancak şifreleme gerektiren ya da büyük mesajlar HTTPS/TCP event channel’a gidiyor
İstemci tarafındaki C++ istemci
libcurlkullanıyor; varsayılan zaman aşımı ayarları uzun polling’e uygun değil.libcurlbağlantıyı kesip yeni bir istek oluşturuyor; bunun sonucunda mesaj kaybı veya tekrarları oluşabiliyorSunucu tarafında Apache, gerçek simülasyon sunucusunun önünde durup ilgisiz bağlantı denemelerini filtreliyor; Apache’nin de kendi zaman aşımı var, bu da bağlantıyı kesip istemcinin yeniden denemesine yol açıyor
Mesaj sıra numaralarıyla kaybın önüne geçilmeye çalışılıyor, ancak Second Life sunucusu istemcinin onay amacıyla geri gönderdiği sıra numaralarını yok sayıyor. Open Simulator’ın bazı uyumlu sunucuları da sıralı numaraları atlayabiliyor
Sonuçta güvenilir olması gereken mesajları kaybedebilen veya çoğaltabilen HTTPS tabanlı bir sistem ortaya çıkıyor. Bazı mesajlar kaybolursa oyun içi kullanıcı etkinliği durup kalıyor
Bunu tasarlayan kişiler çoktan ayrılmış ve mevcut çalışanlar bu karmaşanın ne kadar ciddi olduğunu bilmiyordu. Dış kullanıcılar sorunu bulup belgelemek zorunda kaldı; şirket çalışanları aylardır düzeltmeye çalışıyor. Düzeltmesi yeterince zor olduğu için şu anda işi erteleme yönünde görünüyorlar
Bu yüzden uzun polling “aptalca basit” değil. Doğru yaklaşım muhtemelen TCP ve HTTPS katmanlarının zaman aşımına uğramayacağı kadar sık keep-alive mesajı göndermek. Böylece Apache ve
libcurl’ün düzgün çalıştığı yolda kalınır