ใช้ Service Worker เพื่อจัดการการแจ้งเตือน

Kate Jeffreys
Kate Jeffreys

ใน Codelab นี้ คุณจะต้องใช้ Service Worker เพื่อจัดการการแจ้งเตือน ต่อไปนี้เป็นคำแนะนำว่าคุณคุ้นเคยกับ Service Worker และข้อมูลพื้นฐานเกี่ยวกับการขอสิทธิ์การแจ้งเตือนและการส่งการแจ้งเตือน หากต้องการทบทวนการแจ้งเตือน โปรดดูที่ เริ่มต้นใช้งาน Notifications API Codelab ดูข้อมูลเพิ่มเติมเกี่ยวกับโปรแกรมทำงานของบริการได้ที่ข้อมูลเบื้องต้นเกี่ยวกับโปรแกรมทำงานของบริการของ Matt Gaunt

รีมิกซ์แอปตัวอย่างแล้วดูในแท็บใหม่

ระบบจะบล็อกการแจ้งเตือนจากแอป Glitch ที่ฝังโดยอัตโนมัติ คุณจึงดูตัวอย่างแอปในหน้านี้ไม่ได้ แต่ให้ทำดังนี้

  1. คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้
  2. หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ เต็มหน้าจอ

Glitch ควรเปิดขึ้นในแท็บ Chrome ใหม่

ขณะดำเนินการใน Codelab นี้ ให้ทำการเปลี่ยนแปลงโค้ดใน Glitch ที่ฝังอยู่ในหน้านี้ รีเฟรชแท็บใหม่ด้วยแอปที่เผยแพร่อยู่เพื่อดูการเปลี่ยนแปลง

ทำความคุ้นเคยกับแอปตัวอย่างและโค้ดเริ่มต้น

เริ่มด้วยการดูที่แอปที่เผยแพร่อยู่ในแท็บ Chrome ใหม่

  1. กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
  2. คลิกแท็บคอนโซล

  3. ตรวจสอบว่าได้เลือกตัวเลือกข้อมูลในเมนูแบบเลื่อนลงระดับ ข้างช่องตัวกรอง

  4. ในคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บสำหรับแอปที่เผยแพร่อยู่ คุณจะเห็นข้อความคอนโซลต่อไปนี้

    TODO: Implement getRegistration()

    นี่คือข้อความจากสตับฟังก์ชันที่จะใช้ใน Codelab นี้

ตอนนี้เรามาดูโค้ดของแอปตัวอย่างใน Glitch ที่ฝังไว้ในหน้านี้

  1. ใน Glitch ที่ฝัง ให้ดูที่ public/index.js

    • ฟังก์ชันที่คุณจะใช้มี 4 โครงสร้าง ได้แก่ registerServiceWorker, getRegistration, unRegisterServiceWorker และ sendNotification

    • ฟังก์ชัน requestPermission จะขอสิทธิ์ของผู้ใช้เพื่อส่งการแจ้งเตือน หากคุณเริ่มต้นใช้งาน Codelab API การแจ้งเตือน คุณจะสังเกตเห็นว่าใช้ฟังก์ชัน requestPermission ของ Codelab ได้ที่นี่ ความแตกต่างเพียงอย่างเดียวคือตอนนี้เครื่องมือนี้จะอัปเดตอินเทอร์เฟซผู้ใช้ด้วยหลังจากที่แก้ไขคำขอสิทธิ์แล้ว

    • ฟังก์ชัน updateUI จะรีเฟรชปุ่มและข้อความทั้งหมดของแอป

    • ฟังก์ชัน initializePage จะดำเนินการตรวจหาความสามารถของ Service Worker ในเบราว์เซอร์และอัปเดตอินเทอร์เฟซผู้ใช้ของแอป

    • สคริปต์จะรอจนกว่าหน้าเว็บจะโหลดแล้วจึงเริ่มต้น

  2. ใน Glitch ที่ฝัง ให้เปิด public/service-worker.js

    คุณจะต้องเพิ่มโค้ดในแอปเพื่อลงทะเบียนไฟล์นี้เป็น Service Worker

    แม้ว่าไฟล์จะยังไม่ได้ใช้โดยแอป แต่ไฟล์มีรหัสเริ่มต้นที่จะพิมพ์ข้อความไปยังคอนโซลเมื่อมีการเปิดใช้งานโปรแกรมทำงานของบริการ

    คุณจะเพิ่มโค้ดลงใน public/service-worker.js เพื่อจัดการการแจ้งเตือนเมื่อโปรแกรมทำงานของบริการได้รับการแจ้งเตือน

ลงทะเบียน Service Worker

ในขั้นตอนนี้ คุณจะต้องเขียนโค้ดที่เรียกใช้ เมื่อผู้ใช้คลิกลงทะเบียน Service Worker ใน UI ของแอป โค้ดนี้จะลงทะเบียน public/service-worker.js เป็น Service Worker

  1. ในเครื่องมือแก้ไข Glitch ที่ฝัง ให้เปิด public/index.js แทนที่ฟังก์ชัน 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 ที่ได้รับการแก้ไขแล้ว เช่น ฟังก์ชันข้างต้นจะรอผลลัพธ์ของการลงทะเบียน Service Worker ก่อนอัปเดต UI โปรดดูข้อมูลเพิ่มเติมที่ await ใน MDN

  2. ขณะนี้ผู้ใช้สามารถลงทะเบียน Service Worker ได้แล้ว เพื่อรับข้อมูลอ้างอิงเกี่ยวกับออบเจ็กต์การลงทะเบียนโปรแกรมทำงานของบริการ ใน public/index.js ให้แทนที่ฟังก์ชัน getRegistration ด้วยโค้ดต่อไปนี้

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

    ฟังก์ชันข้างต้นใช้ Service Worker API เพื่อรับการลงทะเบียน Service Worker ปัจจุบัน (หากมี) ทำให้การอ้างอิงการลงทะเบียน Service Worker สะดวกสบายขึ้นเล็กน้อย

  • เพื่อให้ฟังก์ชันการลงทะเบียน 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

ในขั้นตอนนี้ คุณจะต้องเขียนโค้ดที่จะทำงานเมื่อผู้ใช้คลิกส่งการแจ้งเตือนใน UI ของแอป โค้ดนี้จะสร้างการแจ้งเตือน ตรวจสอบว่าได้ลงทะเบียน 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 ของโปรแกรมทำงานของบริการจะส่งข้อมูลจากแอปไปยังโปรแกรมทำงานของบริการ โปรดดูข้อมูลเพิ่มเติมในเอกสาร MDN เกี่ยวกับ postMessage

  • โค้ดจะตรวจหาพร็อพเพอร์ตี้ navigator.serviceWorker.controller ก่อนที่จะพยายามเข้าถึงฟังก์ชัน postMessage navigator.serviceWorker.controller จะเป็น null หากไม่มี Service Worker ที่ทำงานอยู่ หรือหากมีการบังคับให้รีเฟรชหน้า (Shift+โหลดซ้ำ) ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของตัวควบคุม ServiceWorker ใน MDN

จัดการการแจ้งเตือนใน Service Worker

ในขั้นตอนนี้ คุณจะต้องเขียนโค้ดใน Service Worker ซึ่งจะจัดการข้อความที่โพสต์ไปยังโปรแกรมและแสดงการแจ้งเตือนแก่ผู้ใช้

ในเครื่องมือแก้ไข Glitch ที่ฝัง ให้เปิด public/service-worker.js เพิ่มโค้ดต่อไปนี้ต่อท้ายไฟล์

// 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 จะจัดการแสดงการแจ้งเตือน แต่ UI หลักของแอปยังคงมีหน้าที่ขอสิทธิ์การแจ้งเตือนจากผู้ใช้ หากไม่ได้รับอนุญาต สัญญาที่ showNotification แสดงจะถูกปฏิเสธ รหัสด้านบนใช้การบล็อก catch เพื่อหลีกเลี่ยงข้อผิดพลาดการปฏิเสธของ Promise ที่ไม่ถูกตรวจจับและจัดการข้อผิดพลาดนี้อย่างสุภาพมากขึ้น

หากพบปัญหา โปรดดูโค้ดที่เสร็จสมบูรณ์ที่ glitch.com/edit/#!/codelab-notifications-service-worker-completed

ไปที่ Codelab ถัดไปในชุดนี้: สร้างเซิร์ฟเวอร์ข้อความ Push