service worker losts ports to communicate with browser after reactivates

230 views Asked by At

I have the following code inside my front-end code:

    const messageChannel = new MessageChannel();

    navigator.serviceWorker.controller.postMessage(
      {
        type: 'INIT_PORT',
      },
      [messageChannel.port2],
    );

And this inside my service worker:

let getVersionPort;

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'INIT_PORT') {
    getVersionPort = event.ports[0];
  }
});

First, it creates my messageChannel and then posts a message with this channel to my serviceWorker. This code runs on my app start.

Next, my service worker registers the message listener and once a message from the client is sent, it checks it and it is a port, so it assigns it to getVersionPort. I can use getVersionPort to communicate with the browser and it works perfectly until my serviceWorker is stopped by browser. After it is stopped and then reactivated, which we do not have controll on, it's code is run from the top to the bottom and getVersionPort gets undefined.

How to solve this issue? How to force serviceWorker to keep value of getVersionPort even when browser suspends and reactivates it?

1

There are 1 answers

0
Jeff Posnick On

What you're suggesting is not possible. Variables that are part of the ServiceWorkerGlobalScope are discarded whenever the service worker stops and then restarts, and you'll need to re-populate them at startup time to ensure that they're available.

Additionally, I'm pretty sure that attempts to serialize a MessagePort to IndexedDB and reuse them later won't work, so you need to establish a "fresh" messaging connection between your service worker and the client page(s) each time it starts up.