सर्विस वर्कर के साथ दोतरफ़ा बातचीत

Andrew Guan
Andrew Guan

कुछ मामलों में, वेब ऐप्लिकेशन को पेज और सर्विस वर्कर.

उदाहरण के लिए: पॉडकास्ट के पीडब्ल्यूए में एक ऐसी सुविधा बनाई जा सकती है जिससे उपयोगकर्ता इसके लिए एपिसोड डाउनलोड कर सके ऑफ़लाइन इस्तेमाल किया जा सकता है और सर्विस वर्कर, पृष्ठ को नियमित रूप से प्रोग्रेस के बारे में सूचित करता रहे, इसलिए मुख्य थ्रेड यूज़र इंटरफ़ेस (यूआई) को अपडेट कर सकता है.

इस गाइड में हम दो-तरफ़ा कम्यूनिकेशन को लागू करने के अलग-अलग तरीके Window और सेवा कर्मचारी के बारे में जानने के लिए अलग-अलग एपीआई, Workbox लाइब्रेरी, और कुछ बेहतर केस.

डायग्राम में एक सर्विस वर्कर और एक पेज को दिखाया गया है, जिससे मैसेज की अदला-बदली होती है.

Workbox का इस्तेमाल करना

workbox-window वर्कबॉक्स लाइब्रेरी के मॉड्यूल विंडो में चलेगा. Workbox क्लास, इंस्टेंस के रजिस्टर किए गए सर्विस वर्कर को मैसेज भेजने के लिए, messageSW() तरीका उपलब्ध कराती है और जवाब का इंतज़ार करें.

यह पेज कोड एक नया Workbox इंस्टेंस बनाता है और सर्विस वर्कर को मैसेज भेजता है डाउनलोड करने के लिए:

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

सर्विस वर्कर, मैसेज लिसनर को दूसरी तरफ़ लागू करता है और सर्विस वर्कर:

const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

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

वर्कबॉक्स विंडो का इस्तेमाल करके, पेज और सर्विस वर्कर के बीच दोतरफ़ा कम्यूनिकेशन दिखाने वाला डायग्राम.

ब्राउज़र एपीआई का इस्तेमाल करना

अगर Workbox लाइब्रेरी आपकी ज़रूरतों के हिसाब से काफ़ी नहीं है, तो आपके लिए लोअर-लेवल के कई एपीआई उपलब्ध हैं पेजों और सर्विस वर्कर के बीच "टू-वे" कम्यूनिकेशन लागू करना. दोनों में कुछ समानताएं हैं और अंतर:

समानताएं:

  • सभी मामलों में, कम्यूनिकेशन postMessage() इंटरफ़ेस से एक सिरे से शुरू होता है और हमें मिल जाता है दूसरे सिरे पर, message हैंडलर लागू करके.
  • व्यावहारिक तौर पर, सभी उपलब्ध एपीआई हमें एक जैसे इस्तेमाल के उदाहरण लागू करने की अनुमति देते हैं. हालांकि, इनमें से कुछ मामलों में कुछ मामलों में डेवलपमेंट को आसान बना सकता है.

अंतर:

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

ब्रॉडकास्ट चैनल एपीआई

ब्राउज़र सहायता

  • Chrome: 54.
  • एज: 79.
  • Firefox: 38.
  • Safari: 15.4.

सोर्स

Broadcast Channel API ब्राउज़ करते समय के संदर्भ BroadcastChannel के ज़रिए बुनियादी कम्यूनिकेशन करने की सुविधा देता है ऑब्जेक्ट होते हैं.

इसे लागू करने के लिए, पहले हर कॉन्टेक्स्ट को एक ही आईडी वाले BroadcastChannel ऑब्जेक्ट को इंस्टैंशिएट करना होगा और इससे संदेश भेजें और पाएं:

const broadcast = new BroadcastChannel('channel-123');

BroadcastChannel ऑब्जेक्ट, किसी भी सुनने वाले को मैसेज भेजने के लिए postMessage() इंटरफ़ेस दिखाता है कॉन्टेक्स्ट:

//send message
broadcast.postMessage({ type: 'MSG_ID', });

कोई भी ब्राउज़र कॉन्टेक्स्ट BroadcastChannel के onmessage तरीके से मैसेज सुन सकता है ऑब्जेक्ट:

//listen to messages
broadcast.onmessage = (event) => {
  if (event.data && event.data.type === 'MSG_ID') {
    //process message...
  }
};

जैसा कि देखा जा सकता है, यहां किसी विशेष संदर्भ का कोई स्पष्ट संदर्भ नहीं है, इसलिए रेफ़रंस के लिए पहले सर्विस वर्कर या किसी खास क्लाइंट से संपर्क करने की कोशिश करते हैं.

ब्रॉडकास्ट चैनल ऑब्जेक्ट का इस्तेमाल करके, पेज और सर्विस वर्कर के बीच दो-तरफ़ा कम्यूनिकेशन दिखाने वाला डायग्राम.

इसका नुकसान यह है कि यह स्क्रिप्ट लिखते समय, एपीआई को Chrome, Firefox से सहायता मिलती है और Edge ब्राउज़र पर काम नहीं करता, लेकिन Safari जैसे ब्राउज़र पर यह सुविधा काम नहीं करती अभी तक.

क्लाइंट API

ब्राउज़र सहायता

  • Chrome: 40.
  • एज: 17.
  • Firefox: 44.
  • Safari: 11.1.

सोर्स

Client API की मदद से, आपको उन सभी चालू टैब को दिखाने वाले सभी WindowClient ऑब्जेक्ट का रेफ़रंस जिन्हें सर्विस वर्कर कंट्रोल कर रहा है.

पेज को एक ही सर्विस वर्कर कंट्रोल करता है. इसलिए, यह पेज serviceWorker इंटरफ़ेस से सीधे सक्रिय सर्विस वर्कर:

//send message
navigator.serviceWorker.controller.postMessage({
  type: 'MSG_ID',
});

//listen to messages
navigator.serviceWorker.onmessage = (event) => {
  if (event.data && event.data.type === 'MSG_ID') {
    //process response
  }
};

इसी तरह, सर्विस वर्कर, onmessage लिसनर को लागू करके मैसेज सुनता है:

//listen to messages
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'MSG_ID') {
    //Process message
  }
});

अपने किसी भी क्लाइंट से संपर्क करने के लिए, सर्विस वर्कर को लागू करके WindowClient ऑब्जेक्ट जैसे कि Clients.matchAll() और Clients.get(). तो यह काम कर सकता है इनमें से किसी एक को postMessage():

//Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
  if (clients && clients.length) {
    //Respond to last focused tab
    clients[0].postMessage({type: 'MSG_ID'});
  }
});
डायग्राम में एक सर्विस वर्कर को दिखाया गया है, जो क्लाइंट के कई ग्रुप से बातचीत कर रहा है.

सर्विस वर्कर के सभी चालू टैब के साथ आसानी से कम्यूनिकेट करने के लिए, Client API एक अच्छा विकल्प है ज़्यादा आसान तरीके से समझने में मदद मिलती है. यह एपीआई सभी प्रमुख कंपनियों के साथ काम करता है ब्राउज़र, हालांकि, ऐसा हो सकता है कि इसके सभी तरीके उपलब्ध न हों. इसलिए, इससे पहले यह पक्का कर लें कि उसे अपनी साइट पर लागू करना.

मैसेज चैनल

ब्राउज़र सहायता

  • Chrome: 2.
  • एज: 12.
  • Firefox: 41.
  • सफ़ारी: 5.

सोर्स

मैसेज चैनल के लिए ज़रूरी शर्तें कम्यूनिकेशन के लिए दो-तरफ़ा कम्यूनिकेशन तय करना और पोर्ट को एक कॉन्टेक्स्ट से दूसरे कॉन्टेक्स्ट में पास करना चैनल.

चैनल शुरू करने के लिए, पेज एक MessageChannel ऑब्जेक्ट को इंस्टैंशिएट करता है और उसका इस्तेमाल करता है रजिस्टर किए गए सर्विस वर्कर को पोर्ट भेजने के लिए. यह पेज, onmessage लिसनर को दूसरे संदर्भ से मैसेज पाने के लिए:

const messageChannel = new MessageChannel();

//Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
  messageChannel.port2,
]);

//Listen to messages
messageChannel.port1.onmessage = (event) => {
  // Process message
};
डायग्राम में एक पेज दिखाया गया है, जो सर्विस वर्कर को पोर्ट करने के लिए इस्तेमाल कर रहा है. इससे दो-तरफ़ा बातचीत हो रही है.

सर्विस वर्कर को पोर्ट मिलता है, वह इसके लिए एक रेफ़रंस सेव करता है और दूसरे को मैसेज भेजने के लिए इसका इस्तेमाल करता है साइड:

let communicationPort;

//Save reference to port
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'PORT_INITIALIZATION') {
    communicationPort = event.ports[0];
  }
});

//Send messages
communicationPort.postMessage({type: 'MSG_ID'});

फ़िलहाल, MessageChannel का इस्तेमाल सभी प्रमुख कंपनियों के लिए किया जा रहा है ब्राउज़र खोलें.

बेहतर एपीआई: बैकग्राउंड सिंक और बैकग्राउंड फ़ेच

इस गाइड में, हमने दो-तरफ़ा बातचीत की तकनीकों को लागू करने के तरीकों के बारे में जाना है. सामान्य मामले, जैसे कि की जाने वाली कार्रवाई के बारे में बताने वाला स्ट्रिंग मैसेज पास करना या यूआरएल की सूची एक कॉन्टेक्स्ट से दूसरे कॉन्टेक्स्ट में कैश मेमोरी में सेव करने के लिए. इस सेक्शन में, हम खास आपके लिए बनाई गई स्थिति: कनेक्टिविटी का न होना और लंबे समय तक डाउनलोड करना.

बैकग्राउंड सिंक

ब्राउज़र सहायता

  • Chrome: 49.
  • एज: 79.
  • Firefox: समर्थित नहीं.
  • Safari: समर्थित नहीं.

सोर्स

कोई चैट ऐप्लिकेशन यह पक्का करना चाह सकता है कि खराब कनेक्टिविटी की वजह से मैसेज कभी न मिटें. कॉन्टेंट बनाने बैकग्राउंड सिंक एपीआई आपको अगर उपयोगकर्ता के पास इंटरनेट कनेक्शन सही तरीके से काम कर रहा है, तो कार्रवाइयों को फिर से रोकने की कोशिश करें. इससे यह पक्का करने में मदद मिलती है कि उपयोगकर्ता जो भी भेजना चाहता है, उसे असल में भेजा जाता है.

postMessage() इंटरफ़ेस के बजाय, पेज sync को रजिस्टर करता है:

navigator.serviceWorker.ready.then(function (swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});

इसके बाद सर्विस वर्कर, मैसेज को प्रोसेस करने के लिए sync इवेंट सुनता है:

self.addEventListener('sync', function (event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

doSomeStuff() फ़ंक्शन को रिस्पॉन्स के तौर पर एक प्रॉमिस देना चाहिए, जो किसी भी चीज़ की सफलता/फ़ेल के बारे में बताता हो करने की कोशिश करते हैं. अगर इससे काम पूरा हो जाता है, तो सिंक पूरा हो जाता है. अगर यह सुविधा काम नहीं करती है, तो फिर से कोशिश करें. फिर से प्रयास करें समन्वयन भी कनेक्टिविटी की इंतज़ार करते हैं, और घातांकीय बैक-ऑफ़ लागू करते हैं.

कार्रवाई पूरी होने के बाद, सर्विस वर्कर पेज के साथ वापस संपर्क करके ऊपर बताए गए किसी भी कम्यूनिकेशन एपीआई का इस्तेमाल करके, यूज़र इंटरफ़ेस (यूआई) को अपडेट करें.

Google Search, बैकग्राउंड में सिंक करने की सुविधा का इस्तेमाल करके, खराब कनेक्टिविटी की वजह से फ़ेल हुई क्वेरी को सेव करके रखता है. इसके बाद, फिर से कोशिश करें उपयोगकर्ता के ऑनलाइन होने पर उन्हें बाद में सेव करना. कार्रवाई पूरी होने के बाद, वे लोगों को नतीजे के बारे में जानकारी देते हैं उपयोगकर्ता को वेब पुश नोटिफ़िकेशन के ज़रिए भेजने के लिए:

डायग्राम में एक पेज दिखाया गया है, जो सर्विस वर्कर को पोर्ट करने के लिए इस्तेमाल कर रहा है. इससे दो-तरफ़ा बातचीत हो रही है.

बैकग्राउंड फ़ेच

ब्राउज़र सहायता

  • Chrome: 74.
  • एज: 79.
  • Firefox: समर्थित नहीं.
  • Safari: समर्थित नहीं.

सोर्स

मैसेज भेजने या कैश मेमोरी में सेव किए जाने वाले यूआरएल की सूची जैसे छोटे कामों के लिए, ये विकल्प अच्छा विकल्प है. अगर कार्य में बहुत ज़्यादा समय लगता है, तो ब्राउज़र सेवा को बंद कर देगा नहीं करते हैं, तो उपयोगकर्ता की निजता और बैटरी को कोई खतरा होता है.

बैकग्राउंड फ़ेच एपीआई इसकी मदद से, सर्विस वर्कर के लिए कोई लंबा टास्क लोड किया जा सकता है. जैसे, फ़िल्में, पॉडकास्ट या लेवल डाउनलोड करना एक गेम खेलना होता है.

पेज से सर्विस वर्कर से संपर्क करने के लिए, इसके बजाय backgroundFetch.fetch का उपयोग करें postMessage():

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.fetch(
    'my-fetch',
    ['/ep-5.mp3', 'ep-5-artwork.jpg'],
    {
      title: 'Episode 5: Interesting things.',
      icons: [
        {
          sizes: '300x300',
          src: '/ep-5-icon.png',
          type: 'image/png',
        },
      ],
      downloadTotal: 60 * 1024 * 1024,
    },
  );
});

BackgroundFetchRegistration ऑब्जेक्ट, पेज को progress इवेंट को सुनने की अनुमति देता है डाउनलोड की प्रोग्रेस:

bgFetch.addEventListener('progress', () => {
  // If we didn't provide a total, we can't provide a %.
  if (!bgFetch.downloadTotal) return;

  const percent = Math.round(
    (bgFetch.downloaded / bgFetch.downloadTotal) * 100,
  );
  console.log(`Download progress: ${percent}%`);
});
डायग्राम में एक पेज दिखाया गया है, जो सर्विस वर्कर को पोर्ट करने के लिए इस्तेमाल कर रहा है. इससे दो-तरफ़ा बातचीत हो रही है.
डाउनलोड की प्रोग्रेस को दिखाने के लिए, यूज़र इंटरफ़ेस (यूआई) को अपडेट किया गया (बाएं). सर्विस वर्कर का धन्यवाद, सभी टैब बंद होने (दाएं) होने पर, कार्रवाई जारी रह सकती है.

अगले चरण

इस गाइड में, हमने पेज और सर्विस वर्कर के बीच बातचीत के सबसे सामान्य मामले के बारे में बताया है (दो तरीकों से बातचीत की सुविधा).

कई बार, किसी व्यक्ति को दूसरे व्यक्ति से बातचीत करने के लिए, सिर्फ़ एक कॉन्टेक्स्ट की ज़रूरत पड़ सकती है. हालांकि, इसके लिए ज़रूरी है कि जवाब. एक-तरफ़ा तकनीकों को लागू करने के लिए, नीचे दी गई गाइड देखें सर्विस वर्कर से लेकर उसके पास तक के आपके पेज. साथ ही, इसमें इस्तेमाल के उदाहरण और प्रोडक्शन के उदाहरण भी शामिल होंगे:

  • इंपेरेटिव कैश मेमोरी गाइड: सर्विस वर्कर को पेज से कैश मेमोरी में सेव किए गए संसाधनों को पहले से सेव करना (उदाहरण के लिए, प्रीफ़ेच करने की स्थिति में).
  • ब्रॉडकास्ट अपडेट: सूचित करने के लिए सर्विस वर्कर के पेज पर कॉल करना (उदाहरण के लिए, webapp का नया वर्शन उपलब्ध है).