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

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

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

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

Уведомления автоматически блокируются из встроенного приложения Glitch, поэтому вы не сможете просмотреть приложение на этой странице. Вместо этого вот что делать:

  1. Нажмите Remix to Edit , чтобы сделать проект доступным для редактирования.
  2. Чтобы просмотреть сайт, нажмите «Просмотреть приложение» . Затем нажмите Полноэкранный режим полноэкранный .

Глюк должен открыться в новой вкладке Chrome.

Работая над этой лабораторией кода, вносите изменения в код встроенного Glitch на этой странице. Обновите новую вкладку с вашим действующим приложением, чтобы увидеть изменения.

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

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

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

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

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

    TODO: Implement getRegistration() .

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

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

  1. Во встроенном Glitch взгляните на public/index.js :

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

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

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

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

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

  2. Во встроенном Glitch откройте public/service-worker.js .

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

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

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

Зарегистрируйте сервисного работника

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

  1. Во встроенном редакторе Glitch откройте 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, если она существует. Это делает получение ссылки на регистрацию сервис-воркера немного более удобным.

  • Чтобы завершить функцию регистрации сервис-воркера, добавьте код для отмены регистрации сервис-воркера. Замените функцию 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 .

Во встроенном редакторе 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 , чтобы получить ссылку на регистрацию сервис-воркера.

  • Метод postMessage сервис-воркера отправляет данные из приложения сервис-воркеру. Дополнительную информацию см. в документации MDN по postMessage .

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

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

На этом этапе вы напишете код в сервис-воркере, который будет обрабатывать отправленные ему сообщения и отображать уведомления пользователю.

Во встроенном редакторе Glitch откройте 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 и обрабатывать эту ошибку более изящно.

Если вы застряли, см. завершенный код на странице glitch.com/edit/#!/codelab-notifications-service-worker-completed .

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