W niektórych sytuacjach skrypt service worker może wymagać aktywnej komunikacji z dowolnym dostępnych dzięki niej kartom, które informują o konkretnym zdarzeniu. Przykłady:
- Informowanie strony o zainstalowaniu nowej wersji skryptu service worker, dzięki czemu strona może wyświetlać przycisk „Zaktualizuj, aby odświeżyć”, aby umożliwić dostęp do nowej funkcji; natychmiast.
- Informowanie użytkownika o zmianie w danych w pamięci podręcznej, która miała miejsce po stronie mechanizmu Service Worker: wskazówkę, np. „Aplikacja jest teraz gotowa do pracy offline”, „Nowa wersja aplikacji dostępnych treści”.
Nazywamy te przypadki użycia, w których skrypt service worker nie musi otrzymywać wiadomości stronę, aby rozpocząć komunikację: „aktualizacje transmisji”. W tym przewodniku omówimy różne sposobów implementacji tego typu komunikacji między stronami a skryptami service worker za pomocą interfejsów API w przeglądarce i biblioteki Workspace.
Sprawy produkcyjne
Tinder,
PWA Tinder wykorzystuje workbox-window
do nasłuchiwania
ważnych momentów cyklu życia mechanizmów Service Worker na stronie („zainstalowane”, „kontrolowane” i
„aktywowano”). Dzięki temu, gdy pojawia się nowy skrypt service worker, wyświetla się komunikat „Dostępna aktualizacja”
aby odświeżyć PWA i uzyskać dostęp do najnowszych funkcji:
Dynia
W Squoosh PWA, jeśli skrypt service worker zbuforuje wszystkie niezbędne aby umożliwić działanie offline, wysyła na stronę komunikat z komunikatem „Gotowy do pracy offline” z informacją o tej funkcji:
Korzystanie z Workbox
Wykrywaj zdarzenia cyklu życia skryptu service worker
workbox-window
udostępnia prosty interfejs umożliwiający uwzględnianie ważnego cyklu życia mechanizmów Service Worker
wydarzeń.
Biblioteka wykorzystuje w niej interfejsy API po stronie klienta,
updatefound
i zmiana stanu
i udostępnia detektory zdarzeń wyższego poziomu w obiekcie workbox-window
,
do korzystania z tych zdarzeń.
Ten kod strony pozwala wykryć każdą instalację nowej wersji skryptu service worker: aby można było przekazać je użytkownikowi:
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', (event) => {
if (event.isUpdate) {
// Show "Update App" banner
}
});
wb.register();
Informuj stronę o zmianach w danych pamięci podręcznej
Pakiet Workbox
workbox-broadcast-update
zapewnia standardowy sposób powiadamiania klientów okna o tym, że odpowiedź w pamięci podręcznej została zaktualizowana. To jest
najczęściej używane razem z parametrem StaleThatRevalidate
.
Aby przesyłać aktualizacje, dodaj broadcastUpdate.BroadcastUpdatePlugin
do opcji strategii w
po stronie skryptu service worker:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';
registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new StaleWhileRevalidate({
plugins: [
new BroadcastUpdatePlugin(),
],
})
);
W aplikacji internetowej możesz nasłuchiwać takich zdarzeń:
navigator.serviceWorker.addEventListener('message', async (event) => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.data.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// Do something with cacheName and updatedUrl.
// For example, get the cached content and update
// the content on the page.
const cache = await caches.open(cacheName);
const updatedResponse = await cache.match(updatedUrl);
const updatedText = await updatedResponse.text();
}
});
Korzystanie z interfejsów API przeglądarki
Jeśli funkcje Workbox nie odpowiadają Twoim potrzebom, użyj tej przeglądarki Interfejsy API do wdrożenia „aktualizacji transmisji”:
Interfejs Broadcast Channel API
Skrypt service worker tworzy BroadcastChannel
i rozpocznie wysyłanie
wiadomości do niej. Każdy kontekst (np. strona) zainteresowany otrzymywaniem takich wiadomości może
BroadcastChannel
i zaimplementuj moduł obsługi wiadomości, aby odbierać wiadomości.
Aby poinformować stronę o zainstalowaniu nowego skryptu service worker, użyj tego kodu:
// Create Broadcast Channel to send messages to the page
const broadcast = new BroadcastChannel('sw-update-channel');
self.addEventListener('install', function (event) {
// Inform the page every time a new service worker is installed
broadcast.postMessage({type: 'CRITICAL_SW_UPDATE'});
});
Strona nasłuchuje tych zdarzeń, subskrybując sw-update-channel
:
// Create Broadcast Channel and listen to messages sent to it
const broadcast = new BroadcastChannel('sw-update-channel');
broadcast.onmessage = (event) => {
if (event.data && event.data.type === 'CRITICAL_SW_UPDATE') {
// Show "update to refresh" banner to the user.
}
};
To prosta technika, która jednak ogranicza się do przeglądarki: w tym momencie Safari nie obsługuje tego interfejsu API.
Interfejs API klienta
Interfejs Client API zapewnia prosty
komunikowanie się z wieloma klientami z poziomu skryptu service worker przez iterację
Client
obiektów.
Aby wysłać wiadomość na ostatnią zaznaczoną kartę, użyj tego kodu skryptu service worker:
// Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
if (clients && clients.length) {
// Respond to last focused tab
clients[0].postMessage({type: 'MSG_ID'});
}
});
Strona ma zaimplementowany moduł obsługi wiadomości, który przechwytuje te wiadomości:
// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
// Process response
}
};
Interfejs Client API doskonale nadaje się do przesyłania informacji na wiele aktywnych kart. Interfejs API jest obsługiwany przez wszystkie popularne przeglądarki, ale nie wszystkie dostępne metody tak. Sprawdź obsługę przeglądarek przed za jego pomocą.
Kanał wiadomości
Wymagania Kanału wiadomości
pierwszy krok konfiguracji, przez przekazanie portu ze strony do skryptu service worker, aby ustanowić
kanału komunikacji między nimi. Strona tworzy instancję obiektu MessageChannel
i przekazuje
do skryptu service worker za pomocą interfejsu postMessage()
:
const messageChannel = new MessageChannel();
// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
Strona słucha wiadomości przez zaimplementowanie elementu „onmessage” moduł obsługi na tym porcie:
// Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
Skrypt service worker odbiera port i zapisuje do niego odwołanie:
// Initialize
let communicationPort;
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
Od tego momentu może on wysyłać wiadomości do strony, wywołując postMessage()
w odwołaniu do
port:
// Communicate
communicationPort.postMessage({type: 'MSG_ID' });
Implementacja funkcji MessageChannel
może być bardziej złożona ze względu na konieczność zainicjowania portów, ale
obsługiwane przez wszystkie popularne przeglądarki.
Dalsze kroki
W tym przewodniku omawialiśmy jeden konkretny przypadek komunikacji typu Window to Service Worker: "aktualizacje transmisji". Przeglądane przykłady obejmują nasłuchiwanie ważnego skryptu service worker zdarzeń cyklu życia i powiadamianie strony o zmianach w treści lub danych zapisanych w pamięci podręcznej. Możesz myśleć, o ciekawszych przypadkach użycia, w których skrypt service worker aktywnie komunikuje się ze stroną; bez wcześniejszego dostarczenia wiadomości.
Więcej wzorców komunikacji okien i skryptów usługi znajdziesz tutaj:
- Przewodnik po imperatywnym buforowaniu: wywoływanie skryptu service worker ze strony do z wyprzedzeniem buforować zasoby (np. w scenariuszach wstępnego wczytywania).
- Komunikacja dwukierunkowa: przekazywanie zadania do skryptu service worker (np. pobieranie dużych ilości danych) oraz informowanie strony o postępach.