WebSocketStream: WebSocket API के साथ स्ट्रीम इंटिग्रेट करना

बैकप्रेस लागू करके, अपने ऐप्लिकेशन को WebSocket मैसेज में जाने से रोकें या WebSocket सर्वर पर मैसेज न डालें.

बैकग्राउंड

WebSocket API

WebSocket API यह WebSocket प्रोटोकॉल के लिए JavaScript इंटरफ़ेस उपलब्ध कराता है, इसकी मदद से, बातचीत के दौरान दोतरफ़ा बातचीत शुरू की जा सकती है उपयोगकर्ता के ब्राउज़र और सर्वर के बीच. इस एपीआई की मदद से, सर्वर पर मैसेज भेजे जा सकते हैं और इवेंट के हिसाब से जवाब पाए जा सकते हैं तो जवाब देने के लिए सर्वर पर वोट नहीं डाला जाएगा.

Streams API

Streams API इसकी मदद से JavaScript को नेटवर्क पर मिलने वाले डेटा के हिस्से की स्ट्रीम को प्रोग्राम के हिसाब से ऐक्सेस करने की अनुमति मिलती है और उन्हें मनचाहे तरीके से प्रोसेस करें. स्ट्रीम के संदर्भ में एक अहम सिद्धांत है backpressure. यह वह प्रक्रिया है जिससे एक स्ट्रीम या पाइप चेन पढ़ने या लिखने की स्पीड को कंट्रोल करता है. जब खुद स्ट्रीम या बाद में पाइप चेन में आने वाली स्ट्रीम अब भी व्यस्त हो और अभी ज़्यादा खंड स्वीकार करने के लिए तैयार नहीं है, वह सही तरीके से डिलीवरी को धीमा करने के लिए, चेन के पीछे की ओर सिग्नल भेजता है.

मौजूदा WebSocket API में समस्या है

मिलने वाले मैसेज पर बैक प्रेशर लागू नहीं किया जा सकता

मौजूदा WebSocket API के साथ, मैसेज पर प्रतिक्रिया देने में WebSocket.onmessage सर्वर से मैसेज मिलने पर EventHandler कॉल किया जाता है.

मान लें कि आपके पास कोई ऐसा ऐप्लिकेशन है, जिसे भारी डेटा क्रंचिंग ऑपरेशन करने की ज़रूरत है को ईमेल भेजने के लिए. शायद आप नीचे दिए गए कोड से मिलता-जुलता फ़्लो सेट अप करेंगे, और आपने process() कॉल का नतीजा await किया है. इसलिए, आपको अच्छा होना चाहिए, है न?

// A heavy data crunching operation.
const process = async (data) => {
  return new Promise((resolve) => {
    window.setTimeout(() => {
      console.log('WebSocket message processed:', data);
      return resolve('done');
    }, 1000);
  });
};

webSocket.onmessage = async (event) => {
  const data = event.data;
  // Await the result of the processing step in the message handler.
  await process(data);
};

गलत! मौजूदा WebSocket API में समस्या यह है कि बैकप्रेस को लागू करने का कोई तरीका नहीं है. जब मैसेज, process() तरीके से हैंडल करने से ज़्यादा जल्दी पहुंच जाते हैं, तो तो रेंडर करने की प्रोसेस, उन मैसेज को बफ़र करके मेमोरी भर देगी. 100% CPU उपयोग या दोनों के कारण प्रतिक्रिया नहीं देना.

भेजे गए मैसेज पर बैक प्रेशर लागू करना एर्गोनॉमिक नहीं होता

भेजे गए मैसेज पर बैकप्रेशर लागू किया जा सकता है, लेकिन इसमें पोलिंग शामिल है WebSocket.bufferedAmount प्रॉपर्टी, जो कुशल और गैर-एर्गोनॉमिक है. रीड-ओनली प्रॉपर्टी, सूची में शामिल डेटा के बाइट की संख्या दिखाती है CANNOT TRANSLATE WebSocket.send() लेकिन अभी तक नेटवर्क पर ट्रांसमिट न हुआ हो. सूची में मौजूद पूरा डेटा भेजे जाने के बाद, यह वैल्यू शून्य पर रीसेट हो जाती है. हालाँकि, अगर आप WebSocket.send() पर कॉल करते रहें, चढ़ना जारी रहेगा.

WebSocketStream API क्या है?

WebSocketStream API, गैर-मौजूद या नॉन-एर्गोनॉमिक बैकप्रेस की समस्या के बारे में बताता है जिससे स्ट्रीम को WebSocket API के साथ इंटिग्रेट किया जा सकता है. इसका मतलब है कि बैकप्रेस को बिना किसी और शुल्क के "मुफ़्त" में लागू किया जा सकता है.

WebSocketStream API के लिए, इस्तेमाल के सुझाए गए उदाहरण

उन साइटों के उदाहरण जो इस एपीआई का इस्तेमाल कर सकती हैं:

  • हाई बैंडविथ WebSocket ऐप्लिकेशन, जिन्हें इंटरैक्टिविटी बनाए रखने की ज़रूरत होती है, ख़ास तौर पर, वीडियो और स्क्रीन शेयर करने पर.
  • इसी तरह, वीडियो कैप्चर और अन्य ऐप्लिकेशन, जो ब्राउज़र में काफ़ी डेटा जनरेट करते हैं जिसे सर्वर पर अपलोड करना होता है. बैकप्रेस की मदद से क्लाइंट, मेमोरी में डेटा इकट्ठा करने के बजाय डेटा इकट्ठा करना बंद कर सकता है.

मौजूदा स्थिति

चरण स्थिति
1. जानकारी देने वाला वीडियो बनाएं पूरा हुआ
2. स्पेसिफ़िकेशन का शुरुआती ड्राफ़्ट बनाएं प्रोसेस जारी है
3. लोगों के सुझाव जानें और डिज़ाइन को दोहराएं प्रोसेस जारी है
4. ऑरिजिन ट्रायल पूरा हुआ
5. लॉन्च करें Not started

WebSocketStream API को इस्तेमाल करने का तरीका

शुरुआती उदाहरण

WebSocketStream API, वादे पर आधारित है. इसलिए, यहां मौजूद कॉन्टेंट को समझना आसान है लोड हो रही है. आपको एक नया WebSocketStream बनाना होगा और फिर उसे WebSocket सर्वर का यूआरएल पास करना होगा. इसके बाद, opened से कनेक्शन होने का इंतज़ार करें, जिसकी वजह से ReadableStream और/या WritableStream.

इसके लिए, ReadableStream.getReader() तरीका है, तो आपको आख़िरी बार ReadableStreamDefaultReader, इसके बाद, read() स्ट्रीम पूरी होने तक का डेटा, यानी कि जब तक इससे फ़ॉर्म का कोई ऑब्जेक्ट नहीं दिखता {value: undefined, done: true}.

इसलिए, WritableStream.getWriter() तरीका है, तो आपको आख़िरी बार WritableStreamDefaultWriter, इसके बाद, write() है.

  const wss = new WebSocketStream(WSS_URL);
  const {readable, writable} = await wss.opened;
  const reader = readable.getReader();
  const writer = writable.getWriter();

  while (true) {
    const {value, done} = await reader.read();
    if (done) {
      break;
    }
    const result = await process(value);
    await writer.write(result);
  }

बैकप्रेशर

उस सुविधा का क्या ख्याल है जिसके बारे में दावा किया गया था? जैसा कि मैंने ऊपर लिखा है, आपको यह "मुफ़्त" में मिलता है, इसके लिए अलग से कुछ करने की ज़रूरत नहीं है. अगर process() ज़्यादा समय लेता है, तो अगला मैसेज सिर्फ़ तब दिखेगा, जब पाइपलाइन तैयार हो जाएगी. इसी तरह, WritableStreamDefaultWriter.write() चरण सुरक्षित होने पर ही आगे की प्रोसेस शुरू की जाएगी.

बेहतर उदाहरण

WebSocketStream का दूसरा तर्क, आने वाले समय के एक्सटेंशन की अनुमति देने के लिए एक विकल्प बैग है. फ़िलहाल, सिर्फ़ protocols विकल्प उपलब्ध है. जो WebSocket कंस्ट्रक्टर का दूसरा आर्ग्युमेंट:

const chatWSS = new WebSocketStream(CHAT_URL, {protocols: ['chat', 'chatv2']});
const {protocol} = await chatWSS.opened;

चुने गए protocol और संभावित extensions को शब्दकोश में शामिल किया गया है WebSocketStream.opened प्रॉमिस के ज़रिए उपलब्ध है. लाइव कनेक्शन के बारे में सभी जानकारी इस वादे के ज़रिए दी जाती है, क्योंकि अगर कनेक्शन टूट जाता है, तो यह काम का नहीं होता.

const {readable, writable, protocol, extensions} = await chatWSS.opened;

WebSocketStream कनेक्शन के बारे में जानकारी

इस वेबसाइट पर उपलब्ध जानकारी WebSocket.onclose और WebSocket.onerror इवेंट अब WebSocketStream.closed प्रॉमिस प्रॉमिस के ज़रिए उपलब्ध है. गच्चा देने की घटना होने पर प्रॉमिस अस्वीकार हो जाता है, अगर ऐसा नहीं होता है, तो सर्वर से भेजे गए कोड और वजह का इस्तेमाल किया जाता है.

सभी संभावित स्थिति कोड और उनके मतलब के बारे में यहां बताया गया है CloseEvent स्टेटस कोड की सूची.

const {code, reason} = await chatWSS.closed;

WebSocketStream कनेक्शन बंद करना

WebSocketStream को AbortController. इसलिए, किसी AbortSignal को पास करें WebSocketStream कंस्ट्रक्टर से लिंक करें.

const controller = new AbortController();
const wss = new WebSocketStream(URL, {signal: controller.signal});
setTimeout(() => controller.abort(), 1000);

विकल्प के तौर पर, WebSocketStream.close() तरीके का भी इस्तेमाल किया जा सकता है. लेकिन इसका मुख्य उद्देश्य यह बताना है कि कोड को लोड करता है.

wss.close({code: 4000, reason: 'Game over'});

प्रोग्रेसिव एन्हैंसमेंट और इंटरऑपरेबिलिटी

फ़िलहाल, सिर्फ़ Chrome ऐसा ब्राउज़र है जिस पर WebSocketStream API लागू किया जा सकता है. क्लासिक WebSocket API के साथ इंटरऑपरेबिलिटी के लिए, मिलने वाले मैसेज पर बैकप्रेशर लागू नहीं किया जा सकता. भेजे गए मैसेज पर बैकप्रेशर लागू किया जा सकता है, लेकिन इसमें पोलिंग शामिल है WebSocket.bufferedAmount प्रॉपर्टी, जो कुशल और गैर-एर्गोनॉमिक है.

सुविधा की पहचान

यह देखने के लिए कि WebSocketStream API काम करता है या नहीं, इसका इस्तेमाल करें:

if ('WebSocketStream' in window) {
  // `WebSocketStream` is supported!
}

डेमो

साथ काम करने वाले ब्राउज़र पर, एम्बेड किए गए iframe में WebSocketStream API का इस्तेमाल किया जा सकता है. या सीधे Glitch पर भी.

सुझाव/राय दें या शिकायत करें

Chrome टीम, WebSocketStream API के बारे में आपके अनुभव जानना चाहती है.

हमें एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई में ऐसा कुछ है जो आपकी उम्मीद के मुताबिक काम नहीं करता? या फिर कुछ ऐसे तरीके या प्रॉपर्टी हैं जिन पर आपको अपने आइडिया को लागू करने की ज़रूरत है? क्या आपके पास सुरक्षा मॉडल से जुड़ा कोई सवाल या टिप्पणी है? संबंधित GitHub रेपो पर, स्पेसिफ़िकेशन से जुड़ी समस्या दर्ज करें. या किसी मौजूदा समस्या में अपने विचार जोड़ें.

लागू करने से जुड़ी समस्या की शिकायत करना

क्या आपको Chrome को लागू करने में कोई गड़बड़ी मिली? या क्या लागू करने का तरीका, स्पेसिफ़िकेशन से अलग है? new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. इस बारे में ज़्यादा से ज़्यादा जानकारी दें, वीडियो बनाने के आसान निर्देश दें, और कॉम्पोनेंट बॉक्स में Blink>Network>WebSockets डालें. Glitch, रिप्रोडक्शन के मामलों को जल्दी और आसानी से शेयर करने के लिए बेहतरीन काम करता है.

यह एपीआई काम करता है

क्या आपको WebSocketStream API का इस्तेमाल करना है? आपके सार्वजनिक समर्थन से, Chrome टीम को सुविधाओं को प्राथमिकता देने में सहायता मिलती है और दूसरे ब्राउज़र वेंडर को दिखाता है कि उनके लिए काम करना कितना ज़रूरी है.

हैशटैग का इस्तेमाल करके @ChromiumDev को ट्वीट भेजें #WebSocketStream और हमें बताएं कि उसका इस्तेमाल कहां और कैसे किया जा रहा है.

मददगार लिंक

स्वीकार की गई

WebSocketStream API को Adam Rice ने लागू किया था और युताका हिरानो. हीरो इमेज: दान मूइज ने अनस्प्लैश.