Sử dụng Service Worker để quản lý thông báo

Kate Jeffreys
Kate Jeffreys

Trong lớp học lập trình này, bạn sẽ sử dụng một trình chạy dịch vụ để quản lý thông báo. Hướng dẫn tại đây giả định rằng bạn đã quen thuộc với worker dịch vụ và các kiến thức cơ bản về việc yêu cầu quyền gửi thông báo và gửi thông báo. Nếu bạn cần ôn tập về thông báo, hãy xem lớp học lập trình Bắt đầu sử dụng API Thông báo. Để tìm hiểu thêm về trình chạy dịch vụ, hãy xem bài viết Giới thiệu về trình chạy dịch vụ của Matt Gaunt.

Thông báo sẽ tự động bị chặn khỏi ứng dụng Glitch được nhúng, vì vậy, bạn sẽ không thể xem trước ứng dụng trên trang này. Thay vào đó, dưới đây là những việc cần làm:

  1. Nhấp vào Phối lại để chỉnh sửa để có thể chỉnh sửa dự án.
  2. Để xem trước trang web, hãy nhấn vào Xem ứng dụng. Sau đó, nhấn vào biểu tượng Màn hình toàn cảnh toàn màn hình.

Glitch sẽ mở trong một thẻ Chrome mới.

Khi bạn thực hành theo lớp học lập trình này, hãy thay đổi mã trong Glitch được nhúng trên trang này. Làm mới thẻ mới bằng ứng dụng đang chạy để xem các thay đổi.

Làm quen với ứng dụng mẫu và mã khởi động

Bắt đầu bằng cách xem ứng dụng đang chạy trong thẻ Chrome mới:

  1. Nhấn tổ hợp phím `Ctrl+Shift+J` (hoặc `Command+Option+J` trên máy Mac) để mở DevTools.
  2. Nhấp vào thẻ Bảng điều khiển.

  3. Đảm bảo rằng bạn đã chọn tuỳ chọn Thông tin trong trình đơn thả xuống Cấp bên cạnh hộp Lọc.

  4. Trong bảng điều khiển DevTools cho ứng dụng đang hoạt động, bạn sẽ thấy một thông báo trên bảng điều khiển:

    TODO: Implement getRegistration().

    Đây là thông báo từ một hàm giả mà bạn sẽ triển khai trong lớp học lập trình này.

Bây giờ, hãy xem mã của ứng dụng mẫu trong Glitch được nhúng trên trang này.

  1. Trong Glitch được nhúng, hãy xem public/index.js:

    • Có 4 mã giả lập cho các hàm mà bạn sẽ triển khai: registerServiceWorker, getRegistration, unRegisterServiceWorkersendNotification.

    • Hàm requestPermission yêu cầu người dùng cho phép gửi thông báo. Nếu đã tham gia lớp học lập trình Bắt đầu với API thông báo, bạn sẽ thấy hàm requestPermission của lớp học này được sử dụng ở đây. Điểm khác biệt duy nhất là giờ đây, phương thức này cũng cập nhật giao diện người dùng sau khi phân giải yêu cầu cấp quyền.

    • Hàm updateUI làm mới tất cả các nút và thông báo của ứng dụng.

    • Hàm initializePage thực hiện việc phát hiện tính năng cho chức năng của worker trong trình duyệt và cập nhật giao diện người dùng của ứng dụng.

    • Tập lệnh sẽ chờ cho đến khi trang được tải rồi khởi chạy tập lệnh đó.

  2. Trong Glitch được nhúng, hãy mở public/service-worker.js.

    Như tên gọi, bạn sẽ thêm mã vào ứng dụng để đăng ký tệp này làm worker dịch vụ.

    Mặc dù ứng dụng chưa sử dụng tệp này, nhưng tệp này chứa một số mã khởi động sẽ in thông báo vào bảng điều khiển khi worker dịch vụ được kích hoạt.

    Bạn sẽ thêm mã vào public/service-worker.js để xử lý thông báo khi trình chạy dịch vụ nhận được các thông báo đó.

Đăng ký trình chạy dịch vụ

Ở bước này, bạn sẽ viết mã chạy khi người dùng nhấp vào Register service worker (Đăng ký worker dịch vụ) trong giao diện người dùng của ứng dụng. Mã này sẽ đăng ký public/service-worker.js làm worker dịch vụ.

  1. Trong trình chỉnh sửa nhiễu được nhúng, hãy mở public/index.js. Thay thế hàm registerServiceWorker bằng mã sau:

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

    Xin lưu ý rằng registerServiceWorker sử dụng nội dung khai báo async function để việc xử lý lời hứa trở nên thuận tiện hơn. Điều này cho phép bạn await giá trị đã phân giải của Promise. Ví dụ: hàm ở trên chờ kết quả đăng ký worker dịch vụ trước khi cập nhật giao diện người dùng. Hãy xem phần await trên MDN để biết thêm thông tin.

  2. Giờ đây, người dùng có thể đăng ký một worker dịch vụ, bạn có thể tham chiếu đến đối tượng đăng ký worker dịch vụ. Trong public/index.js, hãy thay thế hàm getRegistration bằng mã sau:

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

    Hàm ở trên sử dụng Service Worker API để lấy thông tin đăng ký worker dịch vụ hiện tại, nếu có. Điều này giúp việc tham chiếu đến việc đăng ký worker dịch vụ trở nên thuận tiện hơn một chút.

  • Để hoàn tất chức năng đăng ký trình chạy dịch vụ, hãy thêm mã để huỷ đăng ký trình chạy dịch vụ. Thay thế hàm unRegisterServiceWorker bằng mã sau:

    // 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
    ();
    }

Trong thẻ mà bạn đang xem ứng dụng trực tiếp, hãy tải lại trang. Giờ đây, các nút Register service worker (Đăng ký trình chạy dịch vụ) và Unregister service worker (Huỷ đăng ký trình chạy dịch vụ) sẽ hoạt động.

Gửi thông báo cho nhân viên dịch vụ

Ở bước này, bạn sẽ viết mã sẽ chạy khi người dùng nhấp vào Gửi thông báo trong giao diện người dùng của ứng dụng. Mã này sẽ tạo một thông báo, kiểm tra để đảm bảo rằng một worker dịch vụ đã được đăng ký, sau đó gửi thông báo đến worker dịch vụ bằng phương thức postMessage.

Trong trình chỉnh sửa Glitch được nhúng, hãy mở public/index.js và thay thế hàm sendNotification bằng mã sau:

// 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.');
   
}
 
}
}

Dưới đây là những gì mã đó đang thực hiện:

  • sendNotification là một hàm không đồng bộ, vì vậy, bạn có thể sử dụng await để tham chiếu đến việc đăng ký worker dịch vụ.

  • Phương thức postMessage của worker dịch vụ sẽ gửi dữ liệu từ ứng dụng đến worker dịch vụ. Hãy xem tài liệu MDN về postMessage để biết thêm thông tin.

  • Mã này kiểm tra xem thuộc tính navigator.serviceWorker.controller có tồn tại hay không trước khi cố gắng truy cập vào hàm postMessage. navigator.serviceWorker.controller sẽ là null nếu không có trình chạy dịch vụ nào đang hoạt động hoặc nếu trang đã được làm mới bắt buộc (Shift+Tải lại). Xem tài liệu về trình điều khiển ServiceWorker trên MDN để biết thêm thông tin.

Xử lý thông báo trong worker dịch vụ

Ở bước này, bạn sẽ viết mã vào Service worker, trình chạy này sẽ xử lý các thông báo được đăng lên đó và hiển thị thông báo cho người dùng.

Trong trình chỉnh sửa Glitch được nhúng, hãy mở public/service-worker.js. Thêm mã sau vào cuối tệp:

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

Dưới đây là giải thích ngắn gọn:

  • self là tham chiếu đến chính worker dịch vụ.

  • Mặc dù worker dịch vụ hiện xử lý việc hiển thị thông báo, nhưng giao diện người dùng chính của ứng dụng vẫn chịu trách nhiệm nhận quyền thông báo từ người dùng. Nếu không được cấp quyền, lời hứa do showNotification trả về sẽ bị từ chối. Mã ở trên sử dụng khối catch để tránh lỗi từ chối Promise chưa phát hiện được và xử lý lỗi này một cách linh hoạt hơn.

Nếu bạn gặp khó khăn, hãy xem glitch.com/edit/#!/codelab-notifications-service-worker-completed để xem mã hoàn chỉnh.

Chuyển sang lớp học lập trình tiếp theo trong loạt bài học này: Xây dựng máy chủ thông báo đẩy.