Dans certains cas, le service worker doit communiquer de manière proactive avec l'un des services onglets qu'il commande pour signaler un événement particulier. Voici quelques exemples :
- Informer la page lorsqu'une nouvelle version du service worker a été installée, afin que la page Possibilité d'afficher un bouton Mettre à jour pour actualiser afin que l'utilisateur puisse accéder à la nouvelle fonctionnalité immédiatement.
- Pour informer l'utilisateur d'une modification des données mises en cache effectuée côté service worker, indiquant un message du type "L'application est désormais prête à fonctionner hors connexion" ou "Nouvelle version du contenu disponible.
Nous appellerons ce type de cas d'utilisation où le service worker n'a pas besoin de recevoir un message la page pour lancer une communication "notifications de diffusion". Dans ce guide, nous passerons en revue différents d'implémenter ce type de communication entre les pages et les service workers, à l'aide d'outils standards et la bibliothèque Workbox.
Cas de production
Tinder
La PWA Tinder utilise workbox-window
pour écouter
les moments importants du cycle de vie d'un service worker sur la page ("installé", "contrôlé" et
"activée"). Ainsi, lorsqu'un nouveau service worker entre en jeu, une mise à jour disponible s'affiche.
afin qu'ils puissent actualiser la PWA et accéder aux dernières fonctionnalités:
Squoosh
Dans la PWA Squoosh, lorsque le service worker a mis en cache toutes les ressources pour qu'elle fonctionne hors connexion, le message "Prêt à fonctionner hors connexion" s'affiche sur la page un toast pour informer l'utilisateur de la fonctionnalité:
<ph type="x-smartling-placeholder">Utiliser Workbox
Écouter les événements de cycle de vie d'un service worker
workbox-window
fournit une interface simple pour écouter le cycle de vie d'un service worker important.
les événements.
En arrière-plan, la bibliothèque utilise des API côté client telles que
updatefound
et statechange
et fournit des écouteurs d'événements de niveau supérieur dans l'objet workbox-window
, ce qui facilite
d'utiliser ces événements.
Le code de page suivant vous permet de détecter chaque installation d'une nouvelle version du service worker : afin de pouvoir le communiquer à l'utilisateur:
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', (event) => {
if (event.isUpdate) {
// Show "Update App" banner
}
});
wb.register();
Informer la page des modifications apportées aux données mises en cache
Package Workbox
workbox-broadcast-update
permet d'informer les clients de la fenêtre qu'une réponse mise en cache a été mise à jour. C'est
généralement utilisé avec le service StalewhileRevalidate
stratégie d'enchères.
Pour diffuser des actualités, ajoutez un broadcastUpdate.BroadcastUpdatePlugin
à vos options de stratégie dans le
côté 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(),
],
})
);
Dans votre application Web, vous pouvez écouter les événements suivants:
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();
}
});
Utiliser les API du navigateur
Si les fonctionnalités proposées par Workbox ne répondent pas à vos besoins, utilisez le navigateur suivant : API permettant d'implémenter les mises à jour de diffusion:
API Broadcast Channel
Le service worker crée un objet BroadcastChannel
objet et commence à envoyer
des messages. Tout contexte (par exemple, une page) intéressé par la réception de ces messages peut instancier
BroadcastChannel
et implémentez un gestionnaire de messages pour recevoir des messages.
Pour informer la page lorsqu'un nouveau service worker est installé, utilisez le code suivant:
// 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'});
});
La page écoute ces événements en s'abonnant à 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.
}
};
Bien qu'il s'agisse d'une technique simple, la compatibilité avec les navigateurs est limitée. Au moment de la rédaction de ce document, Safari n'est pas compatible avec cette API.
API cliente
L'API cliente fournit un outil simple
moyen de communication avec plusieurs clients depuis le service worker en effectuant une itération sur un tableau de
Objets Client
.
Le code de service worker suivant permet d'envoyer un message au dernier onglet sélectionné:
// 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'});
}
});
La page implémente un gestionnaire de messages pour intercepter ces messages:
// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
// Process response
}
};
L'API cliente est une excellente option pour diffuser des informations dans plusieurs onglets actifs, par exemple. La L'API est compatible avec tous les principaux navigateurs, mais pas toutes ses méthodes. Vérifiez la compatibilité des navigateurs avant l'utilisent.
Canal de messagerie
Message Channel requiert
une étape de configuration initiale, qui consiste à transmettre un port de la page au service worker afin d'établir une
de communication entre eux. La page instancie un objet MessageChannel
et transmet une
vers le service worker, via l'interface postMessage()
:
const messageChannel = new MessageChannel();
// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
La page écoute les messages en implémentant une instruction "onmessage" sur ce port:
// Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
Le service worker reçoit le port et enregistre une référence à celui-ci:
// Initialize
let communicationPort;
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
À ce stade, il peut envoyer des messages à la page en appelant postMessage()
dans la référence à la
port:
// Communicate
communicationPort.postMessage({type: 'MSG_ID' });
MessageChannel
peut être plus complexe à implémenter en raison de la nécessité d'initialiser des ports, mais il est
compatible avec les principaux navigateurs.
Étapes suivantes
Dans ce guide, nous avons étudié un cas particulier de communication entre les équipes de service et de fenêtre: "informations concernant la diffusion". Les exemples étudiés incluent l'écoute d'importants service worker des événements du cycle de vie et la communication avec la page en cas de modifications du contenu ou des données mises en cache. Vous pouvez réfléchir de cas d'utilisation plus intéressants où le service worker communique de manière proactive avec la page, sans recevoir de message auparavant.
Pour découvrir d'autres modèles de communication entre Windows et les service workers, consultez la page suivante:
- Guide de mise en cache impérative: appeler un service worker depuis la page vers mettre en cache les ressources à l'avance (par exemple, dans les scénarios de préchargement).
- Communication bidirectionnelle: déléguer une tâche à un service worker (par exemple, un téléchargement important) et tenir la page informée de la progression.