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ẽ dùng một trình chạy dịch vụ để quản lý thông báo. Các hướng dẫn ở đây giả định rằng bạn đã quen thuộc với service worker và thông tin cơ bản về yêu cầu quyền thông báo cũng như gửi thông báo. Nếu bạn cần xem lại thông báo, hãy xem Làm quen với Notifications API (API Thông báo) lớp học lập trình này. Để tìm hiểu thêm về trình chạy dịch vụ, hãy xem Giới thiệu về trình chạy dịch vụ của Matt Gaunt.

Phối lại ứng dụng mẫu và xem ứng dụng đó trong thẻ mới

Thông báo sẽ tự động bị chặn khỏi ứng dụng trục trặc được nhúng, do đó 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 Toàn màn hình toàn màn hình.

Nhiễu sẽ mở ra trong thẻ Chrome mới.

Khi tham gia lớp học lập trình này, hãy thay đổi mã trong sự cố được nhúng trên trang này. Hãy làm mới thẻ mới bằng ứng dụng đang hoạt động để 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 hoạt động trong thẻ Chrome mới:

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

  3. Hãy nhớ chọn mục Thông tin trong trình đơn thả xuống Cấp độ bên cạnh hộp Bộ lọc.

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

    TODO: Implement getRegistration().

    Đây là thông báo từ một mã giả lập 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 nhiễu được nhúng trên trang này.

  1. Trong phần Nhiễu đượ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 Làm quen với API Thông báo, bạn sẽ nhận thấy hàm requestPermission của lớp này được sử dụng ở đây. Điểm khác biệt duy nhất là giờ đây, tính năng này cũng cập nhật giao diện người dùng sau khi giải quyết xong 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 đối với chức năng của trình chạy dịch vụ 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 sự cố đã nhúng, hãy mở public/service-worker.js.

    Như cái tên cho thấy, bạn sẽ thêm mã vào ứng dụng để đăng ký tệp này dưới dạng service worker.

    Mặc dù tệp chưa được ứng dụng sử dụng, nhưng tệp này có chứa một số mã khởi động sẽ in thông báo tới bảng điều khiển khi trình chạy 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ã có thể chạy khi người dùng nhấp vào Đăng ký trình chạy 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 một trình chạy 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. Việc này cho phép bạn await giá trị đã phân giải của Promise. Ví dụ: hàm ở trên đang chờ kết quả của việc đăng ký một trình chạy dịch vụ trước khi cập nhật giao diện người dùng. Xem await trên MDN để biết thêm thông tin.

  2. Giờ đây, người dùng có thể đăng ký trình chạy dịch vụ, bạn có thể lấy thông tin tham chiếu đến đối tượng đăng ký trình chạy 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 API Trình chạy dịch vụ để nhận đăng ký trình chạy dịch vụ hiện tại, nếu có. Nó giúp việc tham chiếu đến đăng ký trình chạy dịch vụ 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ã để hủy đă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. Nút Đăng ký trình chạy dịch vụHuỷ đăng ký trình chạy dịch vụ hiện đang 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 Send a notification (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 thông báo, kiểm tra xem trình chạy dịch vụ đã được đăng ký hay chưa, sau đó gửi thông báo cho trình chạy dịch vụ đó bằng phương thức postMessage.

Trong trình chỉnh sửa nhiễu đượ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à chức năng của mã đó:

  • 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 quá trình đăng ký trình chạy dịch vụ.

  • Phương thức postMessage của trình chạy dịch vụ sẽ gửi dữ liệu từ ứng dụng đến trình chạy 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 sự hiện diện của thuộc tính navigator.serviceWorker.controller 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 bị buộc làm mới (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 trình chạy 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 nhiễu đượ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 trình chạy dịch vụ.

  • Mặc dù giờ đây trình chạy dịch vụ sẽ 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 yêu cầu người dùng cấp quyền thông báo. Nếu không được cấp quyền, lời hứa do showNotification trả về sẽ bị từ chối. Đoạn mã ở trên sử dụng khối catch để tránh lỗi từ chối Promise chưa nắm bắt được và xử lý lỗi này linh hoạt hơn một chút.

Nếu bạn gặp khó khăn, hãy truy cập vào glitch.com/edit/#!/codelab-notifications-service-worker-completed để biết mã đã hoàn tất.

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.