Używanie skryptu service worker do zarządzania powiadomieniami

Kate Jeffreys
Kate Jeffreys

W tych ćwiczeniach z programowania użyjesz service workera do zarządzania powiadomieniami. Zakładamy, że znasz już service workerów oraz podstawy związane z prośbą o uprawnienia do wysyłania powiadomień i z wysyłaniem powiadomień. Jeśli chcesz sobie przypomnieć, jak działają powiadomienia, zapoznaj się z samouczkiem Pierwsze kroki z interfejsem Notifications API. Więcej informacji o skryptach service worker znajdziesz we wprowadzeniu do skryptów service worker autorstwa Matta Gaunta.

Zapoznaj się z przykładową aplikacją i kodem początkowym

Zacznij od sprawdzenia aplikacji na żywo na nowej karcie Chrome:

  1. Aby otworzyć Narzędzia dla programistów, naciśnij Ctrl+Shift+J (lub Command+Option+J na Macu).
  2. Kliknij kartę Konsola.

  3. Upewnij się, że w menu Poziomy obok pola Filtr jest wybrana opcja Informacje.

  4. W konsoli Narzędzi deweloperskich w przypadku aplikacji na żywo powinien pojawić się komunikat:

    TODO: Implement getRegistration().

    Jest to wiadomość ze stuba funkcji, którą zaimplementujesz w tym laboratorium.

Przyjrzyjmy się teraz kodowi przykładowej aplikacji.

  1. Spójrz na public/index.js:

    • Istnieją 4 szablony funkcji, które zaimplementujesz: registerServiceWorker, getRegistration, unRegisterServiceWorkersendNotification.

    • Funkcja requestPermission prosi użytkownika o zezwolenie na wysyłanie powiadomień. Jeśli wykonasz ćwiczenie z programowania dotyczące interfejsu Notifications API, zauważysz, że użyto w nim funkcji requestPermission. Jedyna różnica polega na tym, że po rozpatrzeniu prośby o uprawnienia aktualizuje też interfejs.

    • Funkcja updateUI odświeża wszystkie przyciski i wiadomości w aplikacji.

    • Funkcja initializePage wykrywa w przeglądarce funkcje service worker i aktualizuje interfejs aplikacji.

    • Skrypt czeka na załadowanie strony, a następnie ją inicjuje.

  2. Otwórz pokój public/service-worker.js.

    Jak sama nazwa wskazuje, musisz dodać do aplikacji kod, aby zarejestrować ten plik jako service worker.

    Chociaż plik nie jest jeszcze używany przez aplikację, zawiera kod początkowy, który po aktywowaniu komponentu Service Worker wyświetli w konsoli komunikat.

    Dodasz kod do pliku public/service-worker.js, aby obsługiwać powiadomienia, gdy otrzyma je proces roboczy usługi.

Zarejestruj skrypt service worker

W tym kroku napiszesz kod, który będzie uruchamiany, gdy użytkownik kliknie Zarejestruj service worker w interfejsie aplikacji. Ten kod zarejestruje public/service-worker.js jako service worker.

  1. Otwórz pokój public/index.js. Zastąp funkcję registerServiceWorker tym kodem:

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

    Pamiętaj, że registerServiceWorker używa deklaracji async function, aby ułatwić obsługę obietnic. Dzięki temu możesz await rozwiązaną wartość Promise. Na przykład powyższa funkcja czeka na wynik rejestracji service workera, zanim zaktualizuje interfejs. Więcej informacji znajdziesz w sekcji await w MDN.

  2. Teraz, gdy użytkownik może zarejestrować service worker, możesz uzyskać odwołanie do obiektu rejestracji service worker. W pliku public/index.js zastąp funkcję getRegistration tym kodem:

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

    Powyższa funkcja korzysta z interfejsu Service Worker API, aby uzyskać bieżącą rejestrację skryptu service worker, jeśli taka istnieje. Ułatwia to uzyskanie odniesienia do rejestracji service workera.

  • Aby uzupełnić funkcję rejestracji skryptu service worker, dodaj kod, który wyrejestruje skrypt service worker. Zastąp funkcję unRegisterServiceWorker tym kodem:

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

Na karcie, na której wyświetlasz aplikację na żywo, załaduj ponownie stronę. Przyciski Zarejestruj skrypt service workerWyrejestruj skrypt service worker powinny teraz działać.

Wysyłanie powiadomień do komponentu Service Worker

W tym kroku napiszesz kod, który będzie uruchamiany, gdy użytkownik kliknie Wyślij powiadomienie w interfejsie aplikacji. Ten kod utworzy powiadomienie, sprawdzi, czy zarejestrowano proces roboczy usługi, a następnie wyśle powiadomienie do procesu roboczego usługi za pomocą metody postMessage.

Otwórz public/index.js i zastąp funkcję sendNotification tym kodem:

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

Oto co robi ten kod:

  • sendNotification to funkcja asynchroniczna, więc możesz użyć await, aby uzyskać odwołanie do rejestracji service workera.

  • Metoda postMessage w usłudze Service Worker wysyła dane z aplikacji do usługi Service Worker. Więcej informacji znajdziesz w dokumentacji MDN na temat postMessage.

  • Kod sprawdza, czy istnieje właściwość navigator.serviceWorker.controller, zanim spróbuje uzyskać dostęp do funkcji postMessage. Wartość navigator.serviceWorker.controller będzie równa null, jeśli nie ma aktywnego skryptu service worker lub jeśli strona została odświeżona wymuszenie (Shift+Ponowne wczytanie). Więcej informacji znajdziesz w dokumentacji kontrolera ServiceWorker w MDN.

Obsługa powiadomień w usłudze Service Worker

W tym kroku napiszesz w usłudze Service Worker kod, który będzie obsługiwać wysyłane do niej wiadomości i wyświetlać użytkownikowi powiadomienia.

Otwórz pokój public/service-worker.js. Na końcu pliku dodaj ten kod:

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

Oto krótkie wyjaśnienie:

  • self to odwołanie do samego service workera.

  • Wyświetlanie powiadomień jest teraz obsługiwane przez proces roboczy usługi, ale główny interfejs aplikacji nadal odpowiada za uzyskiwanie od użytkownika uprawnień do powiadomień. Jeśli uprawnienia nie zostaną przyznane, obietnica zwrócona przez showNotification zostanie odrzucona. Powyższy kod używa bloku catch, aby uniknąć nieobsłużonego błędu odrzucenia Promise i obsłużyć go w bardziej elegancki sposób.

Przejdź do kolejnych ćwiczeń z programowania w tej serii: Tworzenie serwera powiadomień push.