שימוש ב-Service Worker לניהול התראות

Kate Jeffreys
Kate Jeffreys

ב-Codelab הזה תלמדו איך להשתמש ב-service worker כדי לנהל התראות. ההוראות כאן מבוססות על ההנחה שכבר שמעתם על שירותי worker ועל העקרונות הבסיסיים של בקשת הרשאה לקבלת התראות ושליחת התראות. אם אתם צריכים תזכורת לגבי התראות, תוכלו לעיין ב-codelab תחילת העבודה עם Notifications API. מידע נוסף על קובצי שירות זמין במאמר מבוא לקובצי שירות של Matt Gaunt.

ההתראות נחסמות באופן אוטומטי מאפליקציית Glitch המוטמעת, כך שלא תוכלו לראות תצוגה מקדימה של האפליקציה בדף הזה. במקום זאת, צריך לבצע את הפעולות הבאות:

  1. לוחצים על Remix to Edit כדי לאפשר עריכה של הפרויקט.
  2. כדי לראות תצוגה מקדימה של האתר, מקישים על הצגת האפליקציה. לאחר מכן מקישים על מסך מלא מסך מלא.

Glitch אמור להיפתח בכרטיסייה חדשה ב-Chrome.

במהלך העבודה ב-codelab הזה, תוכלו לבצע שינויים בקוד ב-Glitch המוטמע בדף הזה. כדי לראות את השינויים, צריך לרענן את הכרטיסייה החדשה עם האפליקציה הפעילה.

מעיינים באפליקציה לדוגמה ובקוד ההתחלה

מתחילים בבדיקה של האפליקציה הפעילה בכרטיסייה החדשה ב-Chrome:

  1. מקישים על Control+Shift+J (או על Command+Option+J ב-Mac) כדי לפתוח את DevTools.
  2. לוחצים על הכרטיסייה מסוף.

  3. מוודאים שהאפשרות מידע מסומנת בתפריט הנפתח רמות לצד התיבה סינון.

  4. במסוף DevTools של האפליקציה הפעילה, אמורה להופיע הודעת מסוף:

    TODO: Implement getRegistration().

    זוהי הודעה מקטעי קוד של פונקציות שתטמיעו ב-codelab הזה.

עכשיו נסתכל על הקוד של האפליקציה לדוגמה ב-Glitch המוטמע בדף הזה.

  1. ב-Glitch המוטמע, בודקים את public/index.js:

    • יש ארבע stubs לפונקציות שתטמיעו: registerServiceWorker,‏ getRegistration,‏ unRegisterServiceWorker ו-sendNotification.

    • הפונקציה requestPermission מבקשת מהמשתמש הרשאה לשלוח התראות. אם השלמת את הקודלאב 'תחילת העבודה עם Notifications API', תבחין שבקוד הזה נעשה שימוש בפונקציה requestPermission. ההבדל היחיד הוא שהיא מעדכנת עכשיו גם את ממשק המשתמש אחרי פתרון בקשת ההרשאה.

    • הפונקציה updateUI מרעננת את כל הלחצנים וההודעות באפליקציה.

    • הפונקציה initializePage מבצעת זיהוי תכונות של יכולות של שירותים לצד הלקוח בדפדפן ומעדכנת את ממשק המשתמש של האפליקציה.

    • הסקריפט ממתין עד שהדף נטען ואז מאתחלל אותו.

  2. ב-Glitch המוטמע, פותחים את public/service-worker.js.

    כפי שרומז השם, תצטרכו להוסיף לאפליקציה קוד כדי לרשום את הקובץ הזה בתור service worker.

    האפליקציה עדיין לא משתמשת בקובץ, אבל הוא מכיל קוד התחלה שיציג הודעה במסוף כשה-service worker יופעל.

    תוסיפו קוד ל-public/service-worker.js כדי לטפל בהתראות כשהן מתקבלות על ידי ה-service worker.

רישום קובץ השירות (service worker)

בשלב הזה, כותבים קוד שפועל כשהמשתמש לוחץ על רישום של שירות העבודה בממשק המשתמש של האפליקציה. הקוד הזה ירשום את public/service-worker.js כ-service worker.

  1. פותחים את public/index.js בעורך המוטמע של Glitch. מחליפים את הפונקציה registerServiceWorker בקוד הבא:

    // Use the Service Worker API to register a service worker.
    async function registerServiceWorker() {
      await navigator.serviceWorker.register('./service-worker.js')
      updateUI();
    }
    

    שימו לב שב-registerServiceWorker נעשה שימוש בהצהרה async function כדי להקל על הטיפול בהבטחות. כך תוכלו await את הערך המפוקח של Promise. לדוגמה, הפונקציה שלמעלה ממתינה לתוצאה של רישום של עובד שירות לפני שהיא מעדכנת את ממשק המשתמש. מידע נוסף זמין במאמר await ב-MDN.

  2. עכשיו, כשהמשתמש יכול לרשום שירות עבודה, אפשר לקבל הפניה לאובייקט הרישום של שירות העבודה. ב-public/index.js, מחליפים את הפונקציה getRegistration בקוד הבא:

    // Get the current service worker registration.
    function getRegistration() {
      return navigator.serviceWorker.getRegistration();
    }
    

    הפונקציה שלמעלה משתמשת ב-Service Worker API כדי לקבל את הרישום הנוכחי של ה-service worker, אם הוא קיים. כך קל יותר לקבל הפניה לרישום של ה-service worker.

  • כדי להשלים את הפונקציונליות של רישום קובץ השירות, מוסיפים קוד לביטול הרישום של קובץ השירות. מחליפים את הפונקציה unRegisterServiceWorker בקוד הבא:

    // Unregister a service worker, then update the UI.
    async function unRegisterServiceWorker() {
      // Get a reference to the service worker registration.
      let registration = await getRegistration();
      // Await the outcome of the unregistration attempt
      // so that the UI update is not superceded by a
      // returning Promise.
      await registration.unregister();
      updateUI();
    }
    

בכרטיסייה שבה מוצגת האפליקציה הפעילה, טוענים מחדש את הדף. כעת הלחצנים רישום קובץ שירות (service worker) וביטול הרישום של קובץ שירות (service worker) אמורים לפעול.

שליחת התראות ל-service worker

בשלב הזה, כותבים קוד שיופעל כשהמשתמש ילחץ על שליחת התראה בממשק המשתמש של האפליקציה. הקוד הזה יוצר התראה, בודק אם רשום עובד שירות ואז שולח את ההתראה לעובד השירות באמצעות השיטה postMessage שלו.

בעורך Glitch המוטמע, פותחים את public/index.js ומחליפים את הפונקציה sendNotification בקוד הבא:

// Create and send a test notification to the service worker.
async function sendNotification() {
  // Use a random number as part of the notification data
  // (so you can tell the notifications apart during testing!)
  let randy = Math.floor(Math.random() * 100);
  let notification = {
    title: 'Test ' + randy,
    options: { body: 'Test body ' + randy }
  };
  // Get a reference to the service worker registration.
  let registration = await getRegistration();
  // Check that the service worker registration exists.
  if (registration) {
    // Check that a service worker controller exists before
    // trying to access the postMessage method.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.postMessage(notification);
    } else {
      console.log('No service worker controller found. Try a soft reload.');
    }
  }
}

זה מה שהקוד הזה עושה:

  • sendNotification היא פונקציה אסינכרונית, כך שאפשר להשתמש ב-await כדי לקבל הפניה לרישום של ה-service worker.

  • שיטת postMessage של ה-service worker שולחת נתונים מהאפליקציה ל-service worker. מידע נוסף זמין במסמכי התיעוד של MDN בנושא postMessage.

  • הקוד בודק את נוכחות הנכס navigator.serviceWorker.controller לפני שהוא מנסה לגשת לפונקציה postMessage. הערך של navigator.serviceWorker.controller יהיה null אם אין קובץ שירות פעיל, או אם הדף עודכן בכוח (Shift+טעינה מחדש). מידע נוסף זמין במסמכי העזרה בנושא בקר ServiceWorker ב-MDN.

טיפול בהתראות ב-service worker

בשלב הזה, נכתוב קוד ב-service worker שיטפל בהודעות שיישלחו אליו ויציג התראות למשתמש.

פותחים את public/service-worker.js בעורך המוטמע של Glitch. מוסיפים את הקוד הבא לסוף הקובץ:

// Show notification when received
self.addEventListener('message', (event) => {
  let notification = event.data;
  self.registration.showNotification(
    notification.title,
    notification.options
  ).catch((error) => {
    console.log(error);
  });
});

הנה הסבר קצר:

  • self הוא הפניה ל-service worker עצמו.

  • עכשיו ה-service worker מטפל בהצגת ההתראות, אבל ממשק המשתמש הראשי של האפליקציה עדיין אחראי לקבלת הרשאה מהמשתמש להצגת התראות. אם לא ניתנת הרשאה, ההתחייבות שחוזרת מ-showNotification נדחית. בקוד שלמעלה נעשה שימוש בבלוק catch כדי למנוע שגיאת דחייה מסוג Promise שלא תתפס, ולטפל בשגיאה הזו בצורה קצת יותר נעימה.

אם נתקעתם, תוכלו למצוא את הקוד המלא בכתובת glitch.com/edit/#!/codelab-notifications-service-worker-completed.

אפשר להמשיך לקודלאב הבא בסדרה הזו: יצירת שרת התראות דחיפה.