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

Kate Jeffreys
Kate Jeffreys

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

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

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

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

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

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

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

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

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

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

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

    TODO: Implement getRegistration()

    นี่คือข้อความจากสแต็บฟังก์ชันที่คุณจะใช้ในโค้ดแล็บนี้

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

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

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

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

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

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

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

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

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

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

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

ลงทะเบียน Service Worker

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

หากติดขัด ให้ดูโค้ดที่สมบูรณ์ได้ที่ glitch.com/edit/#!/codelab-notifications-service-worker-completed

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