In einigen Szenarien muss der Service Worker proaktiv mit einem der aktiven werden, um über bestimmte Ereignisse informiert zu werden. Beispiele:
- Seite informieren, wenn eine neue Version des Service Workers installiert wurde, damit die Seite kann dem Nutzer die Schaltfläche Update zum Aktualisieren anzeigen, um auf die neue Funktion zuzugreifen. sofort.
- Sie informieren den Nutzer über eine Änderung an den im Cache gespeicherten Daten, die vom Service Worker durchgeführt wurde, indem eine Anzeige wie diese wird angezeigt: „Die App kann jetzt offline verwendet werden.“ oder „Neue Version des Inhalte verfügbar“.
Wir nennen diese Arten von Anwendungsfällen, bei denen der Service Worker keine Nachricht von die Seite, um die Kommunikation mit Updates zu senden zu starten. In diesem Leitfaden behandeln wir verschiedene Möglichkeiten zur Implementierung dieser Art der Kommunikation zwischen den Seiten und Service Workern mithilfe von Browser-APIs und der Workbox-Bibliothek
Produktionsfälle
Tinder
Die Tinder-PWA verwendet workbox-window
zum Anhören von
in wichtigen Momenten des Service Worker-Lebenszyklus („installiert“, „gesteuert“
„aktiviert“). Wenn dann ein neuer Service Worker ins Spiel kommt, wird die Meldung Update verfügbar angezeigt.
Banner, damit sie die PWA aktualisieren und auf die neuesten Funktionen zugreifen können:
Squoosh
Wenn der Service Worker in der Squoosh-PWA alle erforderlichen damit es offline verwendet werden kann, wird eine Meldung an die Seite gesendet, Toast an und informiert die Nutzenden über die Funktion:
<ph type="x-smartling-placeholder">Workbox verwenden
Service Worker-Lebenszyklusereignisse überwachen
workbox-window
bietet eine einfache Schnittstelle, mit der der wichtige Service Worker-Lebenszyklus überwacht werden kann
Events
Intern nutzt die Bibliothek clientseitige APIs wie
updatefound
und statechange
und stellt Ereignis-Listener auf höherer Ebene im workbox-window
-Objekt bereit, was den
um diese Ereignisse zu verarbeiten.
Mit dem folgenden Seitencode erkennen Sie, wann eine neue Version des Service Workers installiert wird, damit Sie es den Nutzenden mitteilen können:
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', (event) => {
if (event.isUpdate) {
// Show "Update App" banner
}
});
wb.register();
Seite über Änderungen an Cache-Daten informieren
Das Workbox-Paket
workbox-broadcast-update
bietet eine Standardmethode, um Window-Clients zu benachrichtigen, dass eine im Cache gespeicherte Antwort aktualisiert wurde. Dies ist
am häufigsten in Verbindung mit der Methode StaleOnceRevalidation" verwendet
Strategie.
Füge zum Übertragen von Aktualisierungen ein broadcastUpdate.BroadcastUpdatePlugin
zu deinen Strategieoptionen in der
Service Worker-Seite:
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(),
],
})
);
In Ihrer Webanwendung können Sie beispielsweise auf folgende Ereignisse warten:
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();
}
});
Browser-APIs verwenden
Wenn die von Workbox bereitgestellte Funktionalität für Ihre Anforderungen nicht ausreicht, verwenden Sie den folgenden Browser. APIs zur Implementierung von Broadcast-Updates:
Broadcast-Channel-API
Der Service Worker erstellt einen BroadcastChannel
Objekt und sendet das
Nachrichten an sie senden. Jeder Kontext (z.B. eine Seite), der am Erhalt dieser Nachrichten interessiert ist, kann ein
BroadcastChannel
-Objekt und implementieren Sie einen Nachrichten-Handler, um Nachrichten zu empfangen.
Verwenden Sie den folgenden Code, um die Seite zu informieren, wenn ein neuer Service Worker installiert wird:
// 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'});
});
Die Seite erfasst diese Ereignisse, indem sie sw-update-channel
abonniert:
// 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.
}
};
Dies ist eine einfache Methode, aber ihre Einschränkung ist die Browserunterstützung: Safari unterstützt diese API nicht.
Client-API
Die Client API bietet eine einfache
Art der Kommunikation mit mehreren Clients vom Service Worker durch Iteration über ein Array von
Client
-Objekten
Verwenden Sie den folgenden Service Worker-Code, um eine Nachricht an den letzten hervorgehobenen Tab zu senden:
// 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'});
}
});
Auf der Seite wird ein Nachrichten-Handler implementiert, um diese Nachrichten abzufangen:
// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
// Process response
}
};
Die Client API eignet sich hervorragend für Fälle wie das Übertragen von Informationen an mehrere aktive Tabs. Die Das API wird von allen gängigen Browsern unterstützt, nicht alle Methoden jedoch. Browserunterstützung vor dem verwenden.
Kanal für Nachrichten
Message Channel erfordert
einen ersten Konfigurationsschritt, indem Sie einen Port von der Seite an den Service Worker übergeben, um einen
Kommunikationskanal zwischen ihnen. Die Seite instanziiert ein MessageChannel
-Objekt und übergibt ein
an den Service Worker über die Schnittstelle postMessage()
an:
const messageChannel = new MessageChannel();
// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
Die Seite hört Nachrichten ab, indem ein „onmessage“ implementiert wird Handler an diesem Port:
// Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
Der Service Worker empfängt den Port und speichert einen Verweis darauf:
// Initialize
let communicationPort;
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
Ab diesem Zeitpunkt können Nachrichten an die Seite gesendet werden, indem postMessage()
im Verweis auf die
Port:
// Communicate
communicationPort.postMessage({type: 'MSG_ID' });
MessageChannel
ist möglicherweise komplexer zu implementieren, da Ports initialisiert werden müssen.
die von allen gängigen Browsern unterstützt werden.
Nächste Schritte
In diesem Leitfaden haben wir einen speziellen Fall der Window-zu-Service-Worker-Kommunikation untersucht: "broadcast updates" (Übertragungsupdates). Zu den untersuchten Beispielen gehört das Überwachen von wichtigen Service Workern Lebenszyklus-Ereignisse und Kommunizieren der Seite über Änderungen von Inhalten oder im Cache gespeicherten Daten. Sie können darüber nachdenken, Anwendungsfälle, bei denen der Service Worker proaktiv mit der Seite kommuniziert, ohne vorher eine Nachricht zu erhalten.
Weitere Muster für die Window- und Service Worker-Kommunikation finden Sie hier:
- Leitfaden zum imperativen Caching: Service Worker von der Seite aus aufrufen, im Voraus im Cache speichern (z.B. beim Vorabruf).
- Zwei-Wege-Kommunikation: Aufgaben an einen Service Worker delegieren (z.B. ein umfangreicher Download) und die Seite über den Fortschritt auf dem Laufenden zu halten.