ใน Codelab นี้ คุณจะได้ใช้ Service Worker เพื่อจัดการการแจ้งเตือน คำสั่งที่นี่ถือว่าคุณคุ้นเคยกับ Service Worker และพื้นฐานของการขอสิทธิ์การแจ้งเตือนและการส่งการแจ้งเตือนอยู่แล้ว หากต้องการทบทวนเรื่องการแจ้งเตือน โปรดดู Codelab เริ่มต้นใช้งาน Notifications API ดูข้อมูลเพิ่มเติมเกี่ยวกับ Service Worker ได้ที่ข้อมูลเบื้องต้นเกี่ยวกับ Service Worker ของ Matt Gaunt
ทำความคุ้นเคยกับแอปตัวอย่างและโค้ดเริ่มต้น
เริ่มต้นด้วยการดูแอปที่ใช้งานจริงในแท็บ Chrome ใหม่
- กด `Control+Shift+J` (หรือ `Command+Option+J` ใน Mac) เพื่อเปิด DevTools
คลิกแท็บคอนโซล
ตรวจสอบว่าได้เลือกตัวเลือกข้อมูลในเมนูแบบเลื่อนลงระดับ ข้างช่องตัวกรอง
ในคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บของแอปที่ใช้งานจริง คุณควรเห็นข้อความคอนโซลต่อไปนี้
TODO: Implement getRegistration()
นี่คือข้อความจากฟังก์ชัน Stub ที่คุณจะใช้ใน Codelab นี้
ตอนนี้มาดูโค้ดของแอปตัวอย่างกัน
ดูข้อมูลใน
public/index.js
โดยมี Stub 4 รายการสำหรับฟังก์ชันที่คุณจะใช้ ได้แก่
registerServiceWorker
,getRegistration
,unRegisterServiceWorker
และsendNotification
ฟังก์ชัน
requestPermission
จะขอสิทธิ์จากผู้ใช้เพื่อส่งการแจ้งเตือน หากคุณทำ Codelab เริ่มต้นใช้งาน Notifications API คุณจะเห็นว่ามีการใช้ฟังก์ชันrequestPermission
ที่นี่ ความแตกต่างเพียงอย่างเดียวคือตอนนี้ฟังก์ชันนี้จะอัปเดตอินเทอร์เฟซผู้ใช้หลังจากแก้ไขคำขอสิทธิ์ด้วยฟังก์ชัน
updateUI
จะรีเฟรชปุ่มและข้อความทั้งหมดของแอปinitializePage
ฟังก์ชันจะตรวจหาความสามารถของ Service Worker ในเบราว์เซอร์และอัปเดตอินเทอร์เฟซผู้ใช้ของแอปสคริปต์จะรอจนกว่าหน้าเว็บจะโหลดเสร็จ แล้วจึงเริ่มต้น
เปิด
public/service-worker.js
ตามชื่อที่แนะนำ คุณจะต้องเพิ่มโค้ดลงในแอปเพื่อลงทะเบียนไฟล์นี้เป็น Service Worker
แม้ว่าแอปจะยังไม่ได้ใช้ไฟล์ แต่ไฟล์ก็มีโค้ดเริ่มต้นบางส่วนที่จะพิมพ์ข้อความไปยังคอนโซลเมื่อเปิดใช้งาน Service Worker
คุณจะเพิ่มโค้ดลงใน
public/service-worker.js
เพื่อจัดการการแจ้งเตือนเมื่อ Service Worker ได้รับ
ลงทะเบียน Service Worker
ในขั้นตอนนี้ คุณจะเขียนโค้ดที่ทำงาน
เมื่อผู้ใช้คลิกลงทะเบียน Service Worker ใน UI ของแอป
โค้ดนี้จะลงทะเบียน public/service-worker.js
เป็น Service Worker
เปิด
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
เพื่อให้การจัดการ Promise สะดวกยิ่งขึ้น ซึ่งช่วยให้คุณawait
ค่าที่แก้ไขแล้วของPromise
ได้ เช่น ฟังก์ชันด้านบนจะรอผลลัพธ์ของการลงทะเบียน Service Worker ก่อนที่จะอัปเดต UI ดูข้อมูลเพิ่มเติมได้ที่await
ใน MDNตอนนี้ผู้ใช้ลงทะเบียน Service Worker ได้แล้ว คุณจึงรับข้อมูลอ้างอิงไปยังออบเจ็กต์การลงทะเบียน 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
เปิด 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 ที่จะจัดการข้อความที่โพสต์ไปยัง Service Worker และแสดงการแจ้งเตือนต่อผู้ใช้
เปิด 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
ที่ไม่ได้แคช และจัดการข้อผิดพลาดนี้อย่างราบรื่นยิ่งขึ้น
ไปที่ Codelab ถัดไปในชุดนี้: สร้างเซิร์ฟเวอร์การแจ้งเตือนแบบพุช