Ćwiczenia z programowania: tworzenie serwera powiadomień push

Kate Jeffreys
Kate Jeffreys

Dzięki temu ćwiczeniu w programie dowiesz się krok po kroku, jak utworzyć serwer powiadomień push. Po zakończeniu ćwiczeń z programowania będziesz mieć serwer, który:

  • Śledzi subskrypcje powiadomień push (np. serwer tworzy nowy rekord bazy danych, gdy klient zgadza się na powiadomienia push, i usuwa istniejący rekord bazy danych, gdy klient zrezygnuje)
  • Wysyła powiadomienie push do jednego klienta
  • Wysyła powiadomienie push do wszystkich subskrybowanych klientów

To ćwiczenie w Codelabs ma na celu pomóc Ci w nauce przez działanie. Nie omawiamy zbyt wiele pojęć. W artykule Jak działają powiadomienia push, znajdziesz więcej informacji o pojęciach związanych z powiadomieniami push.

Kod klienta tego ćwiczenia w Codelabs jest już gotowy. W tym ćwiczeniu z programowania wdrożysz tylko serwer. Aby dowiedzieć się, jak wdrożyć klienta powiadomień push, zapoznaj się z przewodnikiem Codelab: tworzenie klienta powiadomień push.

Pełny kod znajdziesz na stronie push-notifications-server-codelab-complete (source).

Zgodność z przeglądarką

Te ćwiczenia z programowania działają w następujących kombinacjach systemów operacyjnych i przeglądarek:

  • Windows: Chrome, Edge
  • macOS: Chrome, Firefox
  • Android: Chrome, Firefox

Wiemy, że te ćwiczenia z programowania nie działają w następujących systemach operacyjnych (lub w kombinacjach systemów operacyjnych i przeglądarek):

  • macOS: Brave, Edge, Safari
  • iOS

Stos aplikacji

  • Serwer jest oparty na pliku Express.js.
  • Biblioteka web-push Node.js obsługuje wszystkie funkcje logiczne powiadomień push.
  • Dane subskrypcji są zapisywane w pliku JSON przy użyciu polecenia lowdb.

Nie musisz korzystać z żadnej z tych technologii, aby wdrożyć powiadomienia push. Wybraliśmy te technologie, ponieważ są one niezawodne, jeśli chodzi o ćwiczenia z programowania.

Konfiguracja

Pobierz edytowalną kopię kodu

W trakcie tego ćwiczenia w Codelabs edytor kodu widoczny po prawej stronie tych instrukcji będzie nazywany interfejsem Glitch.

  1. Aby umożliwić edytowanie projektu, kliknij Zremiksuj do edycji.

Konfigurowanie uwierzytelniania

Aby powiadomienia push działały, musisz skonfigurować serwer i klienta za pomocą kluczy uwierzytelniania. Aby dowiedzieć się, dlaczego tak jest, zapoznaj się z sekcją Podpisywanie żądań protokołu Web push.

  1. Otwórz terminal Glitch, klikając Tools (Narzędzia) i wybierając Terminal.
  2. Uruchom w terminalu polecenie npx web-push generate-vapid-keys. Skopiuj wartości klucza prywatnego i publicznego.
  3. Otwórz aplikację .env i zaktualizuj VAPID_PUBLIC_KEY oraz VAPID_PRIVATE_KEY. Ustaw VAPID_SUBJECT na mailto:test@test.test. Wszystkie te wartości należy ujmować w podwójny cudzysłów. Po wprowadzeniu zmian plik .env powinien wyglądać podobnie do tego:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Zamknij terminal Glitch.
  1. Otwórz pokój public/index.js.
  2. Zastąp VAPID_PUBLIC_KEY_VALUE_HERE wartością swojego klucza publicznego.

Zarządzaj subskrypcjami

Twój klient wykonuje większość czynności związanych z subskrypcją. Serwer musi przede wszystkim zapisać nowe subskrypcje powiadomień push i usunąć stare. Dzięki nim możesz przekazywać wiadomości do klientów w przyszłości. Więcej informacji o procesie subskrypcji znajdziesz w artykule na temat subskrybowania powiadomień push klienta.

Zapisz informacje o nowej subskrypcji

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran pełny ekran.
  1. Kliknij Zarejestruj skrypt service worker na karcie aplikacji. W polu stanu powinien pojawić się komunikat podobny do tego:
Service worker registered. Scope: https://desert-cactus-sunset.glitch.me/
  1. Na karcie aplikacji kliknij Subskrybuj, aby przesłać push. W przeglądarce lub systemie operacyjnym zobaczysz prawdopodobne pytanie, czy chcesz zezwolić witrynie na wysyłanie powiadomień push. Kliknij Zezwól (lub inną wyrażenie, którego używa przeglądarka lub system operacyjny). W polu stanu powinien pojawić się komunikat podobny do tego:
Service worker subscribed to push.  Endpoint: https://fcm.googleapis.com/fcm/send/…
  1. Wróć do kodu, klikając Wyświetl źródło w interfejsie Glitch.
  2. Otwórz dzienniki Glitch Logs, klikając Tools (Narzędzia) i wybierając Logs (Dzienniki). Powinno być widać /add-subscription, a po nim jakieś dane. /add-subscription to adres URL, na który klient wysyła żądanie POST, gdy chce zasubskrybować powiadomienia push. Dane poniżej to informacje o subskrypcji klienta, które musisz zapisać.
  3. Otwórz pokój server.js.
  4. Zaktualizuj logikę modułu obsługi trasy /add-subscription za pomocą tego kodu:
app.post('/add-subscription', (request, response) => {
  console.log('/add-subscription');
  console.log(request.body);
  console.log(`Subscribing ${request.body.endpoint}`);
  db.get('subscriptions')
    .push(request.body)
    .write();
  response.sendStatus(200);
});

Usuń stare informacje o subskrypcji

  1. Wróć na kartę aplikacji.
  2. Kliknij Anuluj subskrypcję powiadomień push.
  3. Zajrzyj jeszcze raz do dzienników usterek. Powinna się pojawić informacja /remove-subscription, a po niej informacje o subskrypcji klienta.
  4. Zaktualizuj logikę modułu obsługi trasy /remove-subscription za pomocą tego kodu:
app.post('/remove-subscription', (request, response) => {
  console.log('/remove-subscription');
  console.log(request.body);
  console.log(`Unsubscribing ${request.body.endpoint}`);
  db.get('subscriptions')
    .remove({endpoint: request.body.endpoint})
    .write();
  response.sendStatus(200);
});

Wyślij powiadomienia

Jak wyjaśniamy w sekcji Wysyłanie wiadomości push, serwer nie wysyła wiadomości push bezpośrednio do klientów. Wykorzystuje do tego usługę push. Zasadniczo Twój serwer rozpoczyna proces przekazywania wiadomości do klientów, wysyłając żądania usługi internetowej (żądania protokołu web push) do usługi internetowej (usługi push) należącej do dostawcy przeglądarki, z którego korzysta użytkownik.

  1. Zaktualizuj logikę modułu obsługi trasy /notify-me za pomocą tego kodu:
app.post('/notify-me', (request, response) => {
  console.log('/notify-me');
  console.log(request.body);
  console.log(`Notifying ${request.body.endpoint}`);
  const subscription = 
      db.get('subscriptions').find({endpoint: request.body.endpoint}).value();
  sendNotifications([subscription]);
  response.sendStatus(200);
});
  1. Zaktualizuj funkcję sendNotifications() tym kodem:
function sendNotifications(subscriptions) {
  // TODO
  // Create the notification content.
  const notification = JSON.stringify({
    title: "Hello, Notifications!",
    options: {
      body: `ID: ${Math.floor(Math.random() * 100)}`
    }
  });
  // Customize how the push service should attempt to deliver the push message.
  // And provide authentication information.
  const options = {
    TTL: 10000,
    vapidDetails: vapidDetails
  };
  // Send a push message to each client specified in the subscriptions array.
  subscriptions.forEach(subscription => {
    const endpoint = subscription.endpoint;
    const id = endpoint.substr((endpoint.length - 8), endpoint.length);
    webpush.sendNotification(subscription, notification, options)
      .then(result => {
        console.log(`Endpoint ID: ${id}`);
        console.log(`Result: ${result.statusCode}`);
      })
      .catch(error => {
        console.log(`Endpoint ID: ${id}`);
        console.log(`Error: ${error} `);
      });
  });
}
  1. Zaktualizuj logikę modułu obsługi trasy /notify-all za pomocą tego kodu:
app.post('/notify-all', (request, response) => {
  console.log('/notify-all');
  response.sendStatus(200);
  console.log('Notifying all subscribers');
  const subscriptions =
      db.get('subscriptions').cloneDeep().value();
  if (subscriptions.length > 0) {
    sendNotifications(subscriptions);
    response.sendStatus(200);
  } else {
    response.sendStatus(409);
  }
});
  1. Wróć na kartę aplikacji.
  2. Kliknij Anuluj subskrypcję powiadomień push, a potem jeszcze raz kliknij Subskrybuj, aby wysyłać wiadomości push. Jest to konieczne tylko dlatego, że jak wspomnieliśmy wcześniej, Glitch uruchamia projekt od nowa za każdym razem, gdy edytujesz kod, a projekt jest skonfigurowany tak, aby usuwać bazę danych po uruchomieniu.
  3. Kliknij Powiadom mnie. Otrzymasz powiadomienie push. Tytuł powinien mieć postać Hello, Notifications!, a treści – ID: <ID>, gdzie <ID> to liczba losowa.
  4. Otwórz swoją aplikację w innych przeglądarkach lub na innych urządzeniach i spróbuj zasubskrybować powiadomienia push, a następnie kliknij przycisk Powiadamiaj wszystkich. To samo powiadomienie powinno pojawić się na wszystkich subskrybowanych urządzeniach (tzn. identyfikator w treści powiadomienia push powinien być taki sam).

Dalsze kroki

  • Przeczytaj artykuł Omówienie powiadomień push, aby lepiej zrozumieć, jak działają powiadomienia push.
  • Jeśli chcesz się dowiedzieć, jak utworzyć klienta, który prosi o zgodę na wyświetlanie powiadomień, subskrybuje urządzenie w celu otrzymywania powiadomień push oraz wykorzystuje skrypt service worker do odbierania wiadomości push i wyświetlania ich jako powiadomień, zajrzyj do artykułu Codelabs: Build a Push Notification (Tworzenie klienta powiadomień push).