NOTE: Using Create-React-App Template... (Modifying the Service Worker in it)
I am using the communication channel api to send a message to a service worker for caching. I use an xmlhttp request because of its progress api since fetch needs an indefinite loader afaik.
So after receiving the data on readystate 4 and status code 200 I go to postMessage to SW. I get logging on client side but don't receive the message in the service worker.
I am developing locally and using a Chrome Extension to allow local testing of SW and Build: https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en
CLIENT SNIPPET
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
const res = JSON.parse(this.responseText);
function sendMessage(msg){
console.log("SEND SW MESSAGE");
const msgChan = new MessageChannel();
// This wraps the message posting/response in a promise, which will resolve if the response doesn't
// contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
// controller.postMessage() and set up the onmessage handler independently of a promise, but this is
// a convenient wrapper.
return new Promise(function(resolve, reject){
console.log("Promise Scope");
msgChan.port1.onmessage = function(event){
event.data.error ? reject(event.data.error) : resolve(event.data);
}
// This sends the message data as well as transferring messageChannel.port2 to the service worker.
// The service worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
navigator.serviceWorker.controller.postMessage(msg, [msgChan.port2]);
});
}
sendMessage(res).then(function(){
console.log("SW MESSAGE SENT");
// Storing Quake Data
that.props.setQuakes(res[0]);
// Storing Three Data Obj - SSR Parsing and Creation
that.props.setThreeData(res[1]);
// Greenlight
that.props.setVizInitSuccess(true);
}).catch(function(err){
console.log("Error Caching Data: "+err);
});
} };
SERVICE WORKER SNIPPET
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
// Set up a listener for messages posted from the service worker.
// The service worker is set to post a message to all its clients once it's run its activation
// handler and taken control of the page, so you should see this message event fire once.
// You can force it to fire again by visiting this page in an Incognito window.
navigator.serviceWorker.onmessage = function(event) {
console.log("SERVICE WORKER RECIEVED MESSAGE");
console.log(event);
event.ports[0].postMessage("SW Says Hello Back!");
if (event.data.requireData == true && 'caches' in window) {
// Check for cache'd data and load
// clients.matchAll().then(clients => {
// clients.forEach(client => {
// console.log(client);
// //send_message_to_client(client, msg).then(m => console.log("SW Received Message: "+m));
// })
// })
// caches.open('threeData').then(function(cache){
// console.log("SW Cache");
// console.log(cache)
// event.ports[0].postMessage(cache);
// });
} else {
// Cache Data
caches.open('threeData').then(function(cache){
cache.put('/data.json', new Response(event.data.json))
});
}
};
...
A: From a page on the same origin, go to Developer Tools > Application > Service Workers. You can also use chrome://inspect/#service-workers to find all running service workers.
Controlled pages can use the ServiceWorker. postMessage() method to send messages to service workers. The service worker can optionally send a response back via the Client. postMessage() , corresponding to the controlled page.
update() The update() method of the ServiceWorkerRegistration interface attempts to update the service worker. It fetches the worker's script URL, and if the new worker is not byte-by-byte identical to the current worker, it installs the new worker.
navigator
used in Service Worker file is WorkerNavigator Interface and not Navigator Interface.
WorkerNavigator is a subset of the Navigator interface allowed to be accessed from a Worker (In this case its Service worker). WorkerNavigator Reference.
So navigator
inside Service worker file doesn't contains serviceWorker
object. So it throws error when you call navigator.serviceWorker.onMessage
.
To receive the messages from client use self.addEventListener
in Service Worker file.
self.addEventListener('message', event => {
console.log(`[Message] event: `, event.data);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With