Используйте Service Worker для управления уведомлениями

Кейт Джеффрис
Kate Jeffreys

В этой практической работе вы будете использовать сервис-воркер для управления уведомлениями . Инструкции здесь предполагают, что вы уже знакомы с сервис-воркерами и основами запроса разрешения на отправку уведомлений и их отправки. Если вам нужно освежить знания об уведомлениях, см . практическую работу «Начало работы с API уведомлений ». Подробнее о сервис-воркерах см. в статье Мэтта Гонта «Введение в сервис-воркеры» .

Ознакомьтесь с примером приложения и стартовым кодом.

Начните с просмотра работающего приложения на новой вкладке Chrome:

  1. Нажмите `Control+Shift+J` (или `Command+Option+J` на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Консоль .

  3. Убедитесь, что в раскрывающемся списке Уровни рядом с полем Фильтр выбран параметр Информация .

  4. В консоли DevTools вашего работающего приложения вы должны увидеть сообщение консоли:

    TODO: Implement getRegistration() .

    Это сообщение из заглушки функции, которую вы реализуете в этой лабораторной работе.

Теперь давайте посмотрим на код примера приложения.

  1. Взгляните на public/index.js :

    • Существует четыре заглушки для функций, которые вы будете реализовывать: registerServiceWorker , getRegistration , unRegisterServiceWorker и sendNotification .

    • Функция requestPermission запрашивает у пользователя разрешение на отправку уведомлений. Если вы выполнили практическую работу «Начало работы с API уведомлений» , то заметите, что здесь используется её функция requestPermission . Единственное отличие заключается в том, что теперь она также обновляет пользовательский интерфейс после обработки запроса на разрешение.

    • Функция updateUI обновляет все кнопки и сообщения приложения.

    • Функция initializePage выполняет обнаружение функций для возможностей Service Worker в браузере и обновляет пользовательский интерфейс приложения.

    • Скрипт ждет, пока страница загрузится, а затем инициализирует ее.

  2. Откройте public/service-worker.js .

    Как следует из названия, вам нужно добавить код в приложение, чтобы зарегистрировать этот файл как service worker .

    Хотя файл еще не используется приложением, он содержит некоторый стартовый код, который выведет сообщение на консоль при активации Service Worker.

    Вам нужно будет добавить код в public/service-worker.js для обработки уведомлений, когда их получает service worker.

Зарегистрируйте работника сферы услуг

На этом этапе вы напишете код, который запускается при нажатии пользователем кнопки «Зарегистрировать сервис-воркер» в пользовательском интерфейсе приложения. Этот код зарегистрирует public/service-worker.js как сервис-воркер.

  1. Откройте 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 . Например, функция выше ожидает результата регистрации сервис-воркера перед обновлением пользовательского интерфейса. Подробнее см. в разделе await на MDN .

  2. Теперь, когда пользователь может зарегистрировать сервис-воркера, вы можете получить ссылку на объект регистрации сервис-воркера. В public/index.js замените функцию getRegistration следующим кодом:

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

    Функция выше использует API 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();
    }
    

Перезагрузите страницу на вкладке, где вы просматриваете работающее приложение. Кнопки «Зарегистрировать сервис-воркера» и «Отменить регистрацию сервис-воркера» теперь должны работать.

Отправлять уведомления сервисному работнику

На этом этапе вы напишете код, который будет запускаться при нажатии пользователем кнопки «Отправить уведомление» в пользовательском интерфейсе приложения. Этот код создаст уведомление, проверит регистрацию сервис-воркера, а затем отправит уведомление сервис-воркеру с помощью его метода 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 сервис-воркера отправляет данные из приложения сервис-воркеру. Подробнее см. в документации MDN по postMessage .

  • Код проверяет наличие свойства navigator.serviceWorker.controller перед попыткой доступа к функции postMessage . navigator.serviceWorker.controller будет null , если нет активного сервис-воркера или страница была принудительно обновлена ( Shift+ Reload ). Подробнее см. в документации по контроллеру ServiceWorker на MDN .

Обработка уведомлений в сервис-воркере

На этом этапе вы напишете код в 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 — это ссылка на самого сервисного работника.

  • Хотя сервис-воркер теперь обрабатывает отображение уведомлений, основной пользовательский интерфейс приложения по-прежнему отвечает за получение разрешения на уведомления от пользователя. Если разрешение не предоставлено, обещание, возвращаемое showNotification отклоняется. В коде выше используется блок catch , чтобы избежать неперехваченной ошибки отклонения Promise и обрабатывать эту ошибку немного более изящно.

Перейдите к следующему практическому занятию в этой серии: создание сервера push-уведомлений .