4 पॉइंट द्वारा GN⁺ 2024-03-19 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • रियल-टाइम वेब ऐप्स में सर्वर-से-क्लाइंट event delivery के लिए Long Polling, WebSockets, SSE, WebRTC, WebTransport में से क्या चुनते हैं, इससे latency, bidirectionality, implementation complexity और operational constraints में बड़ा फर्क पड़ता है
  • WebSockets एक single long-lived connection पर bidirectional communication देता है, लेकिन production में connection loss detection, reconnection और ping-pong heartbeat की वजह से अक्सर Socket.IO जैसी libraries साथ में इस्तेमाल की जाती हैं
  • Server-Sent Events HTTP-आधारित server→client one-way stream है, इसलिए implementation और reconnection handling सरल है, लेकिन default EventSource API में POST body या custom headers भेजने की सीमाएं हैं
  • WebTransport HTTP/3 QUIC-आधारित multiple streams और reliable/unreliable transport को support करता है, लेकिन मार्च 2024 तक यह Working Draft है और Safari/Node.js में native support नहीं है, इसलिए अभी इसे general-purpose option मानना मुश्किल है
  • mobile background termination, प्रति domain connection count limits, enterprise proxies/firewalls, और reconnection के दौरान events छूटने की वजह से real apps में sync recovery logic और infrastructure testing भी साथ चाहिए

रियल-टाइम server-client communication technologies का विकास

  • रियल-टाइम वेब applications में server द्वारा client को events भेजना एक core requirement बन गया है
  • शुरुआती दौर में HTTP के ऊपर चलने वाला Long Polling browser में संभव server-client messaging तरीका था
  • बाद में WebSockets bidirectional communication के लिए ज्यादा मजबूत तरीके के रूप में आया
  • Server-Sent Events(SSE) server से client तक ही भेजे जाने वाले one-way communication को ज्यादा सरलता से उपलब्ध कराता है
  • WebTransport ज्यादा efficient, flexible और scalable तरीका बनने की संभावना रखता है, लेकिन अभी support सीमित है
  • WebRTC को कुछ niche server-client event use cases के लिए consider किया जा सकता है, लेकिन मुख्य option के रूप में扱ने के लिए इसका उद्देश्य अलग है

Long Polling

  • Long Polling सामान्य XHR request से server push communication की नकल करने का तरीका है
  • client server पर request खुली रखता है, और server नया data आने तक response रोक कर रखता है
  • नई जानकारी भेजने के बाद connection बंद हो जाता है, और client तुरंत अगली request फिर शुरू कर देता है
  • traditional periodic polling की तुलना में updates तेज मिलते हैं और अनावश्यक network traffic व server load कम हो सकता है
  • हालांकि WebSockets जैसी real-time technologies से यह कम efficient है, और data transfer timing के आधार पर delay आ सकता है
  • client implementation सरल है, लेकिन backend में यह सुनिश्चित करना कठिन है कि reconnecting client कोई event miss न करे

WebSockets

  • WebSockets client और server के बीच एक single long-lived connection बनाता है और full-duplex communication देता है
  • connection establish होने के बाद HTTP request-response cycle के overhead के बिना दोनों तरफ स्वतंत्र रूप से data भेजा जा सकता है
  • real-time chat, gaming और financial trading platforms जैसे low latency और frequent updates चाहने वाले apps के लिए उपयुक्त है
  • basic WebSocket API इस्तेमाल में आसान है, लेकिन production में connection loss और recreation handling जटिल हो जाती है
  • connection अभी भी usable है या नहीं, यह detect करना मुश्किल होता है, इसलिए आम तौर पर ping-and-pong heartbeat जोड़ा जाता है
  • इस complexity की वजह से कई मामलों में Socket.IO जैसी library का इस्तेमाल किया जाता है, और Socket.IO जरूरत पड़ने पर Long Polling fallback भी देता है

Server-Sent Events

  • Server-Sent Events(SSE) HTTP के ऊपर server updates को client तक push करने का standard तरीका है
  • WebSockets के विपरीत, इसे केवल server→client one-way communication के लिए design किया गया है
  • live news feeds, sports scores और real-time updates जैसी स्थितियों के लिए उपयुक्त है, जहां client को server को messages भेजने की जरूरत नहीं होती
  • SSE को ऐसे समझा जा सकता है कि एक HTTP request पर connection बनाए रखते हुए backend हर event आने पर response की एक-एक line stream करता है
  • browser client में EventSource instance initialize करके event stream प्राप्त किया जाता है
  • EventSource WebSockets के विपरीत connection टूटने पर automatically reconnect करता है
  • server को Content-Type header text/event-stream पर set करना होता है, और SSE specification के अनुसार event type, data payload, event ID, retry timing जैसे fields format करने होते हैं

WebTransport

  • WebTransport web clients और servers के बीच efficient, low-latency communication के लिए API है
  • यह HTTP/3 QUIC protocol का उपयोग करके कई streams पर data भेज सकता है
  • यह reliable transport, unreliable transport और unordered data transfer को साथ support करता है
  • real-time games, live streaming और collaboration platforms जैसे high-performance networking चाहने वाले apps के लिए powerful tool बन सकता है
  • मार्च 2024 तक WebTransport Working Draft स्थिति में है और widely supported नहीं है
  • Safari browser में अभी उपलब्ध नहीं है, और Node.js में भी native support नहीं है
  • support बढ़ने पर भी API बहुत complex है, इसलिए application code में सीधे इस्तेमाल करने की बजाय WebTransport के ऊपर libraries बनने की संभावना ज्यादा है

WebRTC

  • WebRTC browser और mobile apps के अंदर plugins के बिना real-time communication capabilities देने वाला open-source project और API standard है
  • यह browsers के बीच audio, video और data exchange के लिए peer-to-peer connections support करता है
  • NAT और firewalls को पार करने के लिए ICE, STUN, TURN जैसे protocols इस्तेमाल करता है
  • WebRTC client-client interaction के लिए बनाया गया था, लेकिन server को client की तरह act कराकर server-client communication में भी उपयोग किया जा सकता है
  • यह तरीका केवल niche use cases के लिए उपयुक्त है, इसलिए मुख्य options की comparison में इसे बाहर रखा गया है
  • WebRTC के चलने के लिए आखिरकार signaling server चाहिए, और यह server WebSockets, SSE या WebTransport में से किसी एक के ऊपर चलेगा
  • इसी वजह से WebRTC को इन technologies का direct replacement मानने का उद्देश्य कमजोर हो जाता है

Technology-wise मुख्य constraints

  • Bidirectional data transfer

    • एक ही connection पर server data receive करना और client data भेजना केवल WebSockets और WebTransport support करते हैं
    • Long Polling भी theoretical रूप से संभव है, लेकिन existing long-polling connection पर नया data भेजने के लिए extra HTTP request चाहिए, इसलिए recommended नहीं है
    • Long Polling में existing connection को disturb किए बिना अलग HTTP request से client→server data भेजना बेहतर है
    • SSE server को अतिरिक्त data भेजने की capability support नहीं करता
    • basic native EventSource API initial request में भी HTTP body में POST जैसा data नहीं भेज सकता
    • data को URL parameters में डालना पड़ता है, लेकिन credentials server logs, proxies और caches में leak हो सकते हैं, इसलिए security के लिहाज से यह अच्छा नहीं है
    • RxDB इस समस्या से बचने के लिए native EventSource API के बजाय eventsource polyfill का उपयोग करता है, और यह library custom HTTP headers जैसी capabilities जोड़ती है
    • Microsoft का fetch-event-source body data transfer और GET के बजाय POST request इस्तेमाल करने की अनुमति देता है
  • प्रति domain connection count limit

    • अधिकांश modern browsers प्रति domain 6 connections allow करते हैं, और यह limit reliable server→client messaging तरीकों की usability को व्यापक रूप से सीमित करती है
    • 6 connections की limit browser tabs के बीच भी shared होती है, इसलिए एक ही page को कई tabs में खोलने पर tabs को वही connection pool share करना पड़ता है
    • HTTP/1.1 RFC server या proxy प्रति 2 connections का और भी कम आंकड़ा recommend करता है
    • visitors का उपयोग करके DDoS रोकने के लिए यह policy उचित है, लेकिन legitimate server-client communication में कई connections चाहिए हों तो समस्या बन सकती है
    • workaround के लिए HTTP/2 या HTTP/3 का इस्तेमाल करना चाहिए ताकि browser प्रति domain केवल एक connection खोले और multiplexing से data handle करे
    • HTTP/2/HTTP/3 में भी SETTINGS_MAX_CONCURRENT_STREAMS setting actual concurrent streams की संख्या सीमित करती है, और अधिकतर configurations का default 100 concurrent streams होता है
    • EventSource जैसी specific APIs के लिए browser connection limit बढ़ा सकते हैं, लेकिन Chromium और Firefox से जुड़े issues “won’t fix” के रूप में marked हैं
  • Browser apps में connection count घटाना

    • browser apps में यह मानकर चलना चाहिए कि user app को एक साथ कई tabs में खोल सकता है
    • default रूप से हर tab एक server stream connection खोल सकता है, लेकिन अधिकतर मामलों में यह अनावश्यक है
    • कई tabs खुले हों फिर भी केवल single connection खोलकर उसे tabs के बीच share करना संभव है
    • RxDB server और client के बीच केवल एक replication stream बनाए रखने के लिए broadcast-channel npm package के LeaderElection का इस्तेमाल करता है
    • यह package RxDB के बिना भी अन्य applications में standalone रूप से इस्तेमाल किया जा सकता है

Mobile, proxies और firewalls की operational constraints

  • Android और iOS जैसे mobile operating systems में WebSockets सहित open connections को लगातार maintain करना कठिन होता है
  • mobile OS कुछ समय inactivity के बाद app को background में भेज सकता है और open connections बंद कर सकता है
  • यह behavior battery saving और performance optimization के लिए resource management strategy का हिस्सा है
  • developers अक्सर server से client को data भेजते समय persistent connection के बजाय mobile push notifications का इस्तेमाल करते हैं
  • push notifications लगातार open connection के बिना server को app को नए data के बारे में बताने और app behavior या updates trigger करने देती हैं
  • enterprise environments में proxies और firewalls non-HTTP connections को block कर सकते हैं, जिससे WebSocket server को infrastructure में जोड़ना मुश्किल हो सकता है
  • ऐसे environments में HTTP-based SSE enterprise integration के लिए आसान तरीका हो सकता है
  • Long Polling भी केवल normal HTTP requests इस्तेमाल करता है, इसलिए एक option हो सकता है

Performance comparison

  • WebSockets, SSE, Long Polling और WebTransport की तुलना करते समय latency, throughput, server load और scalability को साथ देखना चाहिए
  • Go server implementation में message times test करने वाला realtime-web repo दिखाता है कि WebSockets, WebRTC और WebTransport की performance मिलती-जुलती है
  • WebTransport HTTP/3-based नई technology है, इसलिए मार्च 2024 के बाद और performance optimizations आ सकते हैं
  • WebTransport power usage घटाने के लिए optimized है, लेकिन यह metric test नहीं किया गया
  • Latency

    • WebSockets single persistent connection पर full-duplex communication की वजह से सबसे कम latency देता है
    • SSE भी server→client communication में low latency देता है, लेकिन client को server पर message भेजने के लिए extra HTTP request चाहिए
    • Long Polling हर data transfer के लिए नया HTTP connection बनाता है, इसलिए latency ज्यादा होती है
    • Long Polling में server जिस पल event भेजना चाहता है, अगर client नया connection खोल रहा हो तो latency बहुत बढ़ सकती है
    • WebTransport से WebSockets जैसी low latency मिलने की उम्मीद है, और यह HTTP/3 की अधिक efficient multiplexing और congestion control का उपयोग करता है
  • Throughput

    • WebSockets persistent connection की वजह से high throughput दे सकता है, लेकिन client server की send speed जितनी तेजी से process न कर पाए तो backpressure problem throughput को प्रभावित कर सकती है
    • SSE WebSockets से कम overhead रखता है, इसलिए one-way server→client broadcast में potentially higher throughput दे सकता है
    • Long Polling बार-बार connections खोलने और बंद करने के overhead की वजह से आम तौर पर कम throughput देता है और ज्यादा server resources consume करता है
    • WebTransport single connection के अंदर one-way और bidirectional streams दोनों के लिए high throughput support करने की उम्मीद है, और कई streams चाहिए वाले scenarios में WebSockets से बेहतर हो सकता है
  • Scalability और server load

    • WebSockets में ज्यादा connections बनाए रखने पर server load काफी बढ़ सकता है, जिससे बड़ी user count वाले apps की scalability प्रभावित हो सकती है
    • SSE मुख्यतः server→client updates चाहिए वाले scenarios में ज्यादा scalable है
    • SSE protocol upgrade जैसी WebSocket procedure के बिना normal HTTP request इस्तेमाल करता है, इसलिए connection overhead कम होता है
    • Long Polling frequent connection establishment की वजह से server load बढ़ाता है, इसलिए सबसे कम scalable है और केवल fallback mechanism के रूप में उपयुक्त है
    • WebTransport HTTP/3 की connection और stream handling efficiency के आधार पर high scalability के लिए design किया गया है, और WebSockets व SSE की तुलना में server load घटा सकता है

Use cases के हिसाब से recommendations

  • SSE implementation के लिहाज से सबसे straightforward option है; यह existing HTTP/S protocols इस्तेमाल करके enterprise firewall restrictions और अन्य protocols में आने वाली technical issues से बचना आसान बनाता है
  • इसे Node.js और अन्य server frameworks में आसानी से integrate किया जा सकता है
  • news feeds, stock prices और live event streaming जैसे server→client updates अक्सर चाहिए वाले apps के लिए उपयुक्त है
  • WebSockets continuous bidirectional communication चाहने वाले scenarios में मजबूत है
  • browser games, chat applications और live sports updates जैसे continuous interaction चाहने वाले cases में यह मुख्य option बनता है
  • WebTransport में potential है, लेकिन server framework support व्यापक नहीं है और Node.jsSafari compatibility की कमी है
  • WebTransport HTTP/3 पर निर्भर करता है, और nginx जैसे कई web servers का HTTP/3 support अभी experimental state में है
  • reliable/unreliable data transport दोनों support करने वाली future-facing technology है, लेकिन वर्तमान के अधिकांश use cases के लिए अभी viable option नहीं है
  • Long Polling repeated new HTTP connection establishment की inefficiency और high overhead की वजह से आम तौर पर outdated तरीका है
  • WebSockets या SSE support न करने वाले environments में इसे fallback के रूप में इस्तेमाल किया जा सकता है, लेकिन performance limitations के कारण सामान्य उपयोग recommend नहीं है

Reconnection के दौरान events miss होने की समस्या

  • किसी भी real-time streaming technology के ऊपर feature बनाते समय connection interruption और reconnection situations पर विचार करना चाहिए
  • अगर client connecting, reconnecting या offline है, तो server में हुए events stream के रूप में नहीं मिल सकते
  • अगर server stock prices की तरह हर बार पूरा content stream करता है, तो missed events जरूरी नहीं कि महत्वपूर्ण हों
  • अगर backend केवल partial results stream करता है, तो missed events को अवश्य handle करना चाहिए
  • backend द्वारा per-client यह याद रखना कि कौन से events successfully delivered हुए, scalable नहीं है
  • इस problem को client-side logic से handle करना बेहतर है
  • RxDB Sync Engine दो operation modes का इस्तेमाल करता है
    • checkpoint iteration mode: normal HTTP requests से backend data बार-बार query करके client के फिर से synchronized होने तक catch up करता है
    • event observation mode: real-time stream के updates से client को synchronized state में रखता है
  • client connection टूटने या error होने पर replication कुछ समय के लिए checkpoint iteration mode में switch होता है और तब तक sync करता है जब तक फिर से server जैसी state न हो जाए
  • यह तरीका missed events को compensate करता है और client को हमेशा server के साथ बिल्कुल same state में synchronized रहने देता है

Enterprise infrastructure में check करने योग्य बातें

  • enterprise infrastructure में streaming technologies के साथ व्यापक रूप से problems आ सकती हैं
  • proxies और firewalls traffic block कर सकते हैं या request/response को अनजाने में break कर सकते हैं
  • ऐसे environment में real-time app implement करते समय पहले test करना चाहिए कि चुनी गई technology उस infrastructure में काम करती है या नहीं

1 टिप्पणियां

 
GN⁺ 2024-03-19
Hacker News की राय
  • Server-Sent Events से हमेशा लगाव रहा है। यह सरल है और लिखने/implement करने में आसान है

    • अगर IPv6 हो, तो अब इसे आसानी से पूरी तरह scalable बनाया जा सकता है, और सही तरीके से बनाया जाए तो client को सिर्फ SSE services की सूची देकर यह लगभग stateless जैसा काम करता है, जिससे scale करना बहुत आसान हो जाता है
      WebSocket में usage एक स्तर से ऊपर जाते ही scaling काफी जटिल हो जाती है
    • इसकी सरलता की वजह से CDN के साथ WebSocket की तुलना में कहीं ज्यादा आसानी से scale किया जा सकता है: https://www.fastly.com/blog/server-sent-events-fastly
    • सहमत। हालांकि browser instance में प्रति origin SSE streams की सीमा 6 है, इसलिए client-side complexity जोड़े बिना 6 tabs ही सीमा हो सकती है
      https://crbug.com/275955
    • कमी यह है कि payload को base64 में encode करना पड़ता है या line breaks हटाने पड़ते हैं
      समझ नहीं आता कि इसे बस multipart streaming response क्यों नहीं बनाया गया। वह metadata भी support करता है और बहुत आम तौर पर implemented format है
    • साधारण Apache prefork और PHP पर भी काम करता है
  • कुछ और कमियां भी जान लेनी चाहिए
    WebSocket में flow control (backpressure) और multiplexing नहीं है, इसलिए जरूरत हो तो खुद बनाना पड़ेगा या RSocket जैसा कुछ इस्तेमाल करना होगा। SSE भी binary data सीधे नहीं भेज सकता, इसलिए base64 जैसी encoding चाहिए
    WebTransport इन समस्याओं को handle करता है और HOL blocking भी हल करता है, लेकिन चिंता है कि कहीं Python 2→3 या IPv6 transition जैसा न हो जाए, जहां लोग पुराने version इस्तेमाल करते रहें और upgrade का फायदा कम महसूस हो
    जब तक browsers TCP पर चलते रहेंगे, कुछ networks UDP, और इसलिए HTTP/3/WebTransport, को पूरी तरह block कर सकते हैं

    • HOL blocking समस्या है, लेकिन TCP flow control देता है। अगर आप उसका इस्तेमाल नहीं कर रहे हैं, तो आप HTTP/3 के ऊपर जा रहे हैं
      WebTransport adoption धीमा हो सकता है—यह चिंता पहले TLS transport, HTTP/3, XHR के बारे में भी बिल्कुल इसी तरह कही जा सकती थी। कुछ major browser engines के dominance वाली structure में नए browser features और protocols deploy करना अपेक्षाकृत आसान है
      TCP संभव है इसलिए कुछ networks UDP block करेंगे—यह तर्क वैसा ही है जैसे कहना कि HTTP 1.1 non-TLS संभव है इसलिए HTTP/2 और TLS भी हमेशा block होते रहेंगे। पूरी तरह गलत नहीं है, लेकिन HTTP/2 और खासकर TLS के व्यापक adoption को देखकर लगता है कि यह उतनी बड़ी समस्या नहीं है
    • UDP block करने वाले networks की बात अक्सर सुनता हूं, लेकिन असल में कभी देखा नहीं। UDP पर भी बहुत कुछ चलता है
      छोटे office या फिल्मों जैसी dystopian corporate environments में शायद इसे बंद किया जा सकता है, लेकिन कुछ networks UDP ban कर सकते हैं, यह बात इतनी relevant क्यों है समझ नहीं आता। कुछ networks google.com या wikipedia.com भी block करते हैं, लेकिन उससे वे services fail नहीं हो जातीं
    • WebSocketStream जल्द ही Chrome में आएगा और backpressure जोड़ेगा: https://chromestatus.com/feature/5189728691290112
    • base64 से बेहतर approach के रूप में binary-sse है: https://github.com/luciopaiva/binary-sse
    • ऐसी स्थिति में HTTP/2 फिर भी काम करेगा, इसलिए multiplexing की चिंता कम हो जाती है
  • लेख में WebRTC की explanation सही नहीं है। Client/server WebRTC अलग “signaling server” के बिना भी संभव है, server signaling कर सकता है
    बस कुछ extra round trips चाहिए, अलग server की जरूरत नहीं। WebRTC data channels WebSocket या SSE के विकल्प के रूप में काफी अच्छे से काम करते हैं, खासकर जब HOL blocking से बचना हो। Pion या str0m जैसी कई libraries भी हैं जो लगभग सारा काम कर देती हैं
    WebTransport API complex है, यह बात भी बढ़ा-चढ़ाकर कही लगती है। advanced features की जरूरत न हो तो उन्हें ignore कर सकते हैं, और WebSocket की तरह इस्तेमाल करना हो तो एक bidirectional stream खोलना लगभग काफी है। HOL blocking से बचना हो तो हर message के लिए stream खोल दें। थोड़ा ज्यादा complex है, लेकिन ऐसा नहीं कि library अनिवार्य हो, और GitHub Copilot code भी लिख दे इसकी काफी संभावना है। हालांकि WebTransport अभी mature हो रहा है, इसलिए server libraries ज्यादा नहीं हैं और Safari support का भी इंतजार है

    • Client/server WebRTC को “signaling server” के बिना किया जा सकता है, यह बात अजीब लगती है
      आम तौर पर signaling server WebSocket से implemented होता है। अगर आप existing clients के decentralized bootstrap का सुझाव नहीं दे रहे हैं, तो इसे WebRTC से ही implement नहीं किया जा सकता
  • अगर पारंपरिक “enterprise” और “security” IT infrastructure वाले customers के लिए बना रहे हैं, तो बेहतर है कि refresh button जोड़ें और बात खत्म करें
    मेरे अनुभव में ऐसे environments में real-time features बनाने की कोशिशें लगातार fail होती रही हैं और अंतहीन processes की वजह से उन्हें ठीक भी नहीं किया जा सकता

    • Jetty/CometD दूसरे transport methods काम न करें तो long polling पर fallback करता है
    • सच कहूं तो इस category की technologies में सभी की अपनी समस्याएं हैं, और refresh button भी exception नहीं है
    • browser में refresh button होता है, लेकिन शायद उसे दबाने पर application टूट जाने की संभावना काफी है
  • WebSocket और SSE को बड़े scale पर manage करना बड़ा सिरदर्द बन जाता है। खासकर backend में अलग observability चाहिए, और mobile devices पर बहुत सावधानी से implement न किया जाए तो frontend debugging एक nightmare बन जाती है
    Battery बचाने के लिए devices network को बंद या धीमा कर देते हैं, खासकर तब जब dedicated API के जरिए explicitly I/O न किया जा रहा हो
    नया connection बनाना महंगा operation है, और server को state कहीं न कहीं store करनी पड़ती है। अगर इस state storage layer में समस्या आ जाए, तो client बार-बार retry करते रहते हैं, timeout में फंसते हैं, और हमेशा महंगे operation में अटके रहते हैं। यह throughput को आसानी से control करते हुए database पर धीरे-धीरे load डालने का तरीका भी नहीं है
    Reliability के लिहाज से, मेरे अनुभव में long polling सबसे बेहतर रहा है। Event-driven flow सच में जरूरी हो तब भी frontend का layer-1 backend पर long polling करना, और उस layer-1 का layer-2 backend को WebSocket से subscribe करना—ऐसा 2-layer structure बेहतर है, और reliability control कहीं अच्छा हो जाता है

    • पूरी तरह सहमत। WebSocket और SSE से लोगों को खुद अपने पैर पर कुल्हाड़ी मारते देखा है। Long polling में cost आती है, लेकिन मुझे यह सबसे explainable और scalable approach लगती है
    • SSE long polling को support करता है। Server जब चाहे connection बंद करा सकता है
      SSE automatic reconnection support करता है, और last seen ID भी शामिल करता है ताकि server बिना break के आगे जारी रख सके
    • Linked article में इनमें से काफी बातें cover की गई हैं, और rxdb में कई concerns को कम करने के लिए mechanisms हैं
  • Article में नहीं है, लेकिन short polling भी relevant है। यह server से client को message भेजने का तरीका नहीं है, लेकिन shared hosting जैसे मामलों में, जहां कोई और option न हो, तब भी useful है
    मेरे अनुभव में polling interval लंबा हो, जैसे 20 सेकंड भी, तो भी हर response में messages की list साथ डाल दी जाए तो यह काफी अच्छी तरह काम करता है। User button दबाता है तो client server को request भेजता है, और server data के साथ latest messages की list भी response में भेज देता है, जिससे client latest state में आ जाता है

    • तेजी से बदलते data पर भी लागू हो सकता है। खासकर तब जब polling के दौरान updates शामिल होने का ratio ज्यादा हो
  • मुझे अब तक समझ नहीं आता कि WebSocket और SSE initial request में Authorization जैसे headers भेजने को support क्यों नहीं करते। Real-time service authentication पूरी तरह implementer पर छोड़ दिया जाता है
    Spec में कोई अच्छा तरीका हो सकता है, लेकिन इतने अलग-अलग approaches देखे हैं कि अब लगभग कह सकते हैं कि व्यवहार में ऐसा कोई standard तरीका नहीं है

    • EventSource API में काफी कमियां हैं। मैं सबसे ज्यादा इस्तेमाल होने वाले EventSource polyfill का maintainer हूं, लेकिन हाल ही में मैंने EventSource client को modern तरीके से फिर से बनाने का project शुरू किया है: https://github.com/rexxars/eventsource-client
      Custom headers संभालने के अलावा यह सभी request methods (POST, PATCH आदि), request body शामिल करना, named events को subscribe करना, और initial last event ID set करना भी support करता है। इसे async iterator की तरह भी इस्तेमाल किया जा सकता है
      Server-Sent Events की simplicity अच्छी लगती है, लेकिन EventSource API ऐसा लगता है जैसे जल्दी में implement किया गया और फिर वैसे ही छोड़ दिया गया
      [1]: https://github.com/eventsource/eventsource
    • क्या initial request में पूरे standard HTTP headers और cookies तक नहीं भेजे जा सकते?
    • Cookies भेजी जाती हैं
    • TLS certificates भी हैं
    • कई सालों से इस्तेमाल कर रहा हूं, क्या मैं कुछ miss कर रहा हूं?
  • यह naive सोच हो सकती है, लेकिन HTTP/2 या उससे ऊपर मानकर चलें तो EventSource और message भेजने के लिए fetch() का combination single TCP connection इस्तेमाल करने वाले दूसरे protocols जितना ठीक लगता है। HTTP/3 UDP इस्तेमाल करता है, इसलिए और बेहतर
    धारणा यह है कि connection सिर्फ तब maintain रखना है जब tab foreground में हो। असल में यह तरीका try करने पर कौन-सी समस्याएं आईं, यह जानने की इच्छा है

    • एक limitation यह है कि SSE text-only है, इसलिए binary data efficiently नहीं भेज सकता। base64 जैसी encoding चाहिए
    • एक library है जो आपकी जरूरत पूरी करती है
      https://www.npmjs.com/package/@microsoft/fetch-event-source
    • मैंने भी बिल्कुल यही सोचा था। HTTP/2 और SSE से 99% समस्याएं solve हो जाती हैं, ऐसा लगता है
      पूरी तरह कुछ अलग करने के बजाय, मैं जानना चाहता था कि क्या latency, memory usage और CPU resources को और कम रखते हुए SSE को और आगे push किया जा सकता है
    • अगर main use case server→client है, तो सही है
  • ऐसे articles देखने में थोड़ा मजा आता है। 90s के आखिर में मैंने online auction system design किया था, और XHR requests बिल्कुल नहीं थीं
    Real-time updates सब server-push/HTTP streaming से handle किए जाते थे। उस समय सारे open connections संभालना आसान नहीं था, लेकिन सही architecture हो तो acceptable scale तक संभव था

    • HTTP streaming की अहमियत लोगों को समझाने में मैंने वाकई बहुत समय लगाया, और यह निश्चित रूप से आसान लड़ाई नहीं है
      HTTP/2 या HTTP/3 के फायदे शानदार हैं, लेकिन यह भी जानना जरूरी है कि लगभग हर जगह supported HTTP 1.1 में भी क्या इस्तेमाल किया जा सकता है
  • लंबी polling की थोड़ी याद आती है। नई technologies की तुलना में यह वाकई बहुत simple थी। WebRTC को सबसे बेहतर मानने वाले के तौर पर भी मुझे ऐसा ही लगता है

    • SSE लंबी polling से कोई खास ज़्यादा complex नहीं है। फर्क बस इतना है कि server response भेजने के तुरंत बाद connection बंद नहीं करता
      इसके बजाय वह फिर से data का इंतज़ार करता है और उसी stream में अतिरिक्त response भेजता है
    • काश यह इतना simple होता, लेकिन ऐसा नहीं है
      Second Life की networking “event channel” के लिए लंबी polling HTTPS इस्तेमाल करती है, और server उसी channel के जरिए client को event messages भेजता है। ज्यादातर messages UDP से जाते हैं, लेकिन जिनमें encryption चाहिए या जो बड़े messages होते हैं, वे HTTPS/TCP event channel से जाते हैं
      client-side C++ client libcurl इस्तेमाल करता है, लेकिन default timeout settings लंबी polling के अनुकूल नहीं हैं। libcurl connection तोड़ देता है और नया request बनाता है, जिससे messages खो सकते हैं या duplicate हो सकते हैं
      server-side पर Apache असली simulation server के सामने खड़ा होकर अप्रासंगिक connection attempts को filter करता है, लेकिन Apache के भी अपने timeouts हैं, इसलिए वह connection बंद कर देता है और client को retry करने पर मजबूर करता है
      message sequence numbers से loss रोकने की कोशिश की जाती है, लेकिन Second Life server client द्वारा confirmation के लिए वापस भेजे गए sequence numbers को ignore करता है। Open Simulator के कुछ compatible servers sequence numbers skip भी कर देते हैं
      नतीजा यह है कि HTTPS-based system में वे messages भी खो या duplicate हो सकते हैं जिन्हें reliable होना चाहिए। कुछ messages खो जाएं तो game के अंदर user activity रुक जाती है
      इसे design करने वाले लोग बहुत पहले जा चुके हैं, और मौजूदा employees को नहीं पता था कि यह mess कितना गंभीर है। external users को problem ढूंढकर document करनी पड़ी, और company employees कई महीनों से इसे ठीक करने की कोशिश कर रहे हैं। इसे ठीक करना काफी मुश्किल है, इसलिए फिलहाल लगता है कि काम टालने की तरफ है
      इसलिए लंबी polling “बेवकूफी की हद तक simple” नहीं है। सही तरीका शायद यह है कि keep-alive messages इतनी बार भेजे जाएं कि TCP और HTTPS layers timeout न हों। तब Apache और libcurl ऐसे path पर बने रहते हैं जहां वे ठीक से काम करते हैं
    • यह अब भी अक्सर इस्तेमाल होती है। request overhead स्वीकार करने के बदले सब कुछ मौजूदा HTTP API context के अंदर रखना कई applications में समझदारी है
    • आजकल भी HTTP/2 के साथ लंबी polling इस्तेमाल की जा सकती है, और यह खत्म नहीं होने वाली