सामान्य सूचना पैटर्न

हम वेब पुश के लिए, उन्हें लागू करने के कुछ सामान्य पैटर्न देखने जा रहे हैं.

इसमें सर्विस वर्कर में उपलब्ध कुछ अलग-अलग एपीआई का इस्तेमाल करना होगा.

सूचना बंद करने का इवेंट

पिछले सेक्शन में, हमने देखा कि हम notificationclick इवेंट को कैसे सुन सकते हैं.

एक notificationclose इवेंट भी होता है, जिसे तब कॉल किया जाता है, जब उपयोगकर्ता आपके किसी इवेंट को खारिज करता है सूचनाएं (यानी उपयोगकर्ता, सूचना पर क्लिक करने के बजाय, क्रॉस पर क्लिक करता है या सूचना बंद है).

आम तौर पर, इस इवेंट का इस्तेमाल आंकड़ों के लिए किया जाता है. इससे, यूज़र ऐक्टिविटी को ट्रैक करने में मदद मिलती है.

self.addEventListener('notificationclose', function (event) {
  const dismissedNotification = event.notification;

  const promiseChain = notificationCloseAnalytics();
  event.waitUntil(promiseChain);
});

सूचना में डेटा जोड़ना

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

किसी पुश इवेंट से डेटा लेने और उसे किसी नोटिफ़िकेशन, पास किए गए विकल्प ऑब्जेक्ट में data पैरामीटर जोड़ने के लिए है showNotification() में शेयर किया जाएगा:

const options = {
  body:
    'This notification has data attached to it that is printed ' +
    "to the console when it's clicked.",
  tag: 'data-notification',
  data: {
    time: new Date(Date.now()).toString(),
    message: 'Hello, World!',
  },
};
registration.showNotification('Notification with Data', options);

क्लिक हैंडलर में मौजूद डेटा को event.notification.data से ऐक्सेस किया जा सकता है.

const notificationData = event.notification.data;
console.log('');
console.log('The notification data has the following parameters:');
Object.keys(notificationData).forEach((key) => {
  console.log(`  ${key}: ${notificationData[key]}`);
});
console.log('');

विंडो खोलें

किसी नोटिफ़िकेशन के सबसे सामान्य जवाबों में से एक है विंडो / टैब को किसी खास यूआरएल पर ले जाएं. हम इसकी मदद से ऐसा कर सकते हैं: clients.openWindow() एपीआई.

अपने notificationclick इवेंट में, हम कुछ इस तरह के कोड चलाएं:

const examplePage = '/demos/notification-examples/example-page.html';
const promiseChain = clients.openWindow(examplePage);
event.waitUntil(promiseChain);

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

मौजूदा विंडो पर फ़ोकस करें

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

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

पिछले उदाहरण पर विचार करते हुए, हम कोड को बदलकर यह देखेंगे कि /demos/notification-examples/example-page.html पहले से खुला है.

const urlToOpen = new URL(examplePage, self.location.origin).href;

const promiseChain = clients
  .matchAll({
    type: 'window',
    includeUncontrolled: true,
  })
  .then((windowClients) => {
    let matchingClient = null;

    for (let i = 0; i < windowClients.length; i++) {
      const windowClient = windowClients[i];
      if (windowClient.url === urlToOpen) {
        matchingClient = windowClient;
        break;
      }
    }

    if (matchingClient) {
      return matchingClient.focus();
    } else {
      return clients.openWindow(urlToOpen);
    }
  });

event.waitUntil(promiseChain);

आइए कोड के बारे में जानें.

सबसे पहले हम यूआरएल एपीआई का इस्तेमाल करके, उदाहरण वाले पेज को पार्स करते हैं. मैंने जेफ़ से, एक शानदार तरकीब सीखी है पॉसनिक. location ऑब्जेक्ट का इस्तेमाल करके new URL() को कॉल करने पर अगर पास की गई स्ट्रिंग एक-दूसरे से जुड़ी है, तो पूरे यूआरएल को लौटाता है (यानी / https://example.com/).

हम यूआरएल को सटीक बनाते हैं, ताकि बाद में विंडो के यूआरएल से भी उसका मिलान किया जा सके.

const urlToOpen = new URL(examplePage, self.location.origin).href;

इसके बाद हमें WindowClient ऑब्जेक्ट की एक सूची मिलती है, जो वर्तमान में खुले टैब और विंडो. (याद रखें कि ये सिर्फ़ आपकी साइट के ऑरिजिन के लिए हैं.)

const promiseChain = clients.matchAll({
  type: 'window',
  includeUncontrolled: true,
});

matchAll में दिए गए विकल्प, ब्राउज़र को यह जानकारी देते हैं कि हमें सिर्फ़ "विंडो" खोजने के लिए क्लाइंट टाइप करना (यानी सिर्फ़ टैब और विंडो खोजना और वेब वर्कर को बाहर रखें). includeUncontrolled हमें खोजने की अनुमति देता है आपकी साइट के ऑरिजिन के ऐसे सभी टैब जिन्हें मौजूदा सेवा कंट्रोल नहीं करती वर्कर, यानी इस कोड को चलाने वाला सर्विस वर्कर. आम तौर पर, आपको matchAll() को कॉल करने पर includeUncontrolled हमेशा सही होना चाहिए.

हम वापस किए गए प्रॉमिस को promiseChain के तौर पर कैप्चर करते हैं, ताकि हम इसे लागू कर सकें हमारे सर्विस वर्कर को बचाए रखने के लिए event.waitUntil().

matchAll() प्रॉमिस रिज़ॉल्व होने पर, हम लौटाए गए विंडो क्लाइंट के ज़रिए यह प्रक्रिया दोहराते हैं और उनके यूआरएल की तुलना उस यूआरएल से करें जिसे हम खोलना चाहते हैं. अगर हमें कोई मिलता-जुलता गाना मिलता है, तो हम पर क्लिक करते हैं, जो उस विंडो को उपयोगकर्ताओं के ध्यान में लाएंगे. फ़ोकस इन चीज़ों के साथ किया जाता है: matchingClient.focus() कॉल.

अगर हमें मेल खाने वाला क्लाइंट नहीं मिलता, तो हम पिछले सेक्शन की तरह ही एक नई विंडो खोलते हैं.

.then((windowClients) => {
  let matchingClient = null;

  for (let i = 0; i < windowClients.length; i++) {
    const windowClient = windowClients[i];
    if (windowClient.url === urlToOpen) {
      matchingClient = windowClient;
      break;
    }
  }

  if (matchingClient) {
    return matchingClient.focus();
  } else {
    return clients.openWindow(urlToOpen);
  }
});

सूचनाएं मर्ज की जा रही हैं

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

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

आप यह कर सकते हैं या registration.getNotifications() एपीआई की मदद से, अपने वेब ऐप्लिकेशन पर दिख रही सभी सूचनाओं को ऐक्सेस किया जा सकता है.

चलिए देखते हैं कि चैट के उदाहरण को लागू करने के लिए, हम इस एपीआई का इस्तेमाल कैसे कर सकते हैं.

हमारे चैट ऐप्लिकेशन में, मान लेते हैं कि हर सूचना में कुछ डेटा है और उसमें उपयोगकर्ता नाम भी शामिल है.

हम सबसे पहले हम किसी ऐसे उपयोगकर्ता के लिए कोई खुली सूचना ढूंढना चाहते हैं जिसके पास, उपयोगकर्ता नाम. हम registration.getNotifications() से बात करेंगे और उन पर लूप में जाएंगे. साथ ही, किसी खास उपयोगकर्ता नाम के लिए notification.data:

const promiseChain = registration.getNotifications().then((notifications) => {
  let currentNotification;

  for (let i = 0; i < notifications.length; i++) {
    if (notifications[i].data && notifications[i].data.userName === userName) {
      currentNotification = notifications[i];
    }
  }

  return currentNotification;
});

अगला चरण इस सूचना को एक नई सूचना से बदलना है.

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

.then((currentNotification) => {
  let notificationTitle;
  const options = {
    icon: userIcon,
  }

  if (currentNotification) {
    // We have an open notification, let's do something with it.
    const messageCount = currentNotification.data.newMessageCount + 1;

    options.body = `You have ${messageCount} new messages from ${userName}.`;
    options.data = {
      userName: userName,
      newMessageCount: messageCount
    };
    notificationTitle = `New Messages from ${userName}`;

    // Remember to close the old notification.
    currentNotification.close();
  } else {
    options.body = `"${userMessage}"`;
    options.data = {
      userName: userName,
      newMessageCount: 1
    };
    notificationTitle = `New Message from ${userName}`;
  }

  return registration.showNotification(
    notificationTitle,
    options
  );
});

अगर इस समय कोई सूचना दिख रही है, तो हम मैसेज की संख्या बढ़ाकर, सूचना का टाइटल और मुख्य हिस्सा. अगर वहां कोई सूचना नहीं है, हम 1 में से newMessageCount के साथ नई सूचना बनाते हैं.

इसका नतीजा यह होता है कि पहला मैसेज कुछ ऐसा दिखेगा:

मर्ज किए बिना पहली सूचना.

दूसरी सूचना मिलने पर, सूचनाएं छोटी हो जाएंगी:

मर्ज करने के साथ दूसरी सूचना.

इस तरीके के साथ अच्छी बात यह है कि अगर आपका उपयोगकर्ता सूचनाओं को एक के बाद एक दिखाया जा रहा है. इस तरह वे ज़्यादा सही तरीके से दिखेंगे नोटिफ़िकेशन को नवीनतम संदेश से बदलने के बजाय.

नियम का अपवाद

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

पुश इवेंट में यह देखा जा सकता है कि आपको सूचना दिखानी है या नहीं विंडो क्लाइंट की जांच कर रहा है और एक फ़ोकस विंडो को ढूंढ रहा है.

सभी विंडो पाने और फ़ोकस की गई विंडो खोजने के लिए कोड इस तरह दिखता है:

function isClientFocused() {
  return clients
    .matchAll({
      type: 'window',
      includeUncontrolled: true,
    })
    .then((windowClients) => {
      let clientIsFocused = false;

      for (let i = 0; i < windowClients.length; i++) {
        const windowClient = windowClients[i];
        if (windowClient.focused) {
          clientIsFocused = true;
          break;
        }
      }

      return clientIsFocused;
    });
}

हम clients.matchAll() का इस्तेमाल करते हैं हम अपने सभी विंडो क्लाइंट पाने के लिए, focused पैरामीटर की जांच करते हैं.

अपने पुश इवेंट में, हम इस फ़ंक्शन का इस्तेमाल यह तय करने के लिए करेंगे कि हमें सूचना दिखाने की ज़रूरत है या नहीं:

const promiseChain = isClientFocused().then((clientIsFocused) => {
  if (clientIsFocused) {
    console.log("Don't need to show a notification.");
    return;
  }

  // Client isn't focused, we need to show a notification.
  return self.registration.showNotification('Had to show a notification.');
});

event.waitUntil(promiseChain);

पुश इवेंट से किसी पेज को मैसेज भेजें

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

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

मान लें कि हमें एक अनुरोध मिला है, हमने जांच की है कि हमारा वेब ऐप्लिकेशन मौजूदा समय में फ़ोकस कर रहा है, तो हम "मैसेज पोस्ट" कर सकते हैं प्रत्येक खुले हुए पेज के लिए कुछ इस प्रकार:

const promiseChain = isClientFocused().then((clientIsFocused) => {
  if (clientIsFocused) {
    windowClients.forEach((windowClient) => {
      windowClient.postMessage({
        message: 'Received a push message.',
        time: new Date().toString(),
      });
    });
  } else {
    return self.registration.showNotification('No focused windows', {
      body: 'Had to show a notification instead of messaging each page.',
    });
  }
});

event.waitUntil(promiseChain);

हर पेज में, हम एक मैसेज इवेंट जोड़कर मैसेज सुनते हैं लिसनर:

navigator.serviceWorker.addEventListener('message', function (event) {
  console.log('Received a message from service worker: ', event.data);
});

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

यह बात भी ध्यान में रखें कि अगर आप अपने वेब पेज में मैसेज लिसनर को परिभाषित नहीं करते हैं, सर्विस वर्कर से आने वाले मैसेज से कुछ नहीं होगा.

पेज को कैश मेमोरी में सेव करना और विंडो खोलना

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

इसके लिए fetch इवेंट मैनेज करने के लिए, आपके सर्विस वर्कर को सेट-अप करना ज़रूरी है, अगर fetch इवेंट लिसनर को लागू किया जाता है, तो पेज और ऐसेट को कैश मेमोरी में सेव करके, अपने push इवेंट में इसका फ़ायदा पाएं जिन्हें दिखाने से पहले आपको यह शर्त पूरी करनी होगी.

ब्राउज़र के साथ काम करना

notificationclose इवेंट

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

  • Chrome: 50. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 17. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: 44. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • सफ़ारी: 16. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

Clients.openWindow()

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

  • Chrome: 40. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 17. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: 44. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Safari: 11.1. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

ServiceWorkerRegistration.getNotifications()

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

  • Chrome: 40. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 17. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: 44. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • सफ़ारी: 16. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

clients.matchAll()

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

  • Chrome: 42. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 17. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: 54. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Safari: 11.1. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

ज़्यादा जानकारी के लिए, सर्विस वर्कर का यह परिचय देखें पोस्ट.

आगे कहां जाना है

कोड लैब