2

In a service worker, the client interface has postMessage() for talking to clients, which can be of type "window", "worker", or "sharedworker".

In "window" clients, the message event is sent to navigator.serviceWorker.controller. Example service worker code:

const windowClients = await clients.matchAll({ type: "window" });
windowClients[0].postMessage('Send this message to window.navigator.serviceWorker.controller');

But in shared worker clients, navigator.serviceWorker does not seem to exist. (This seems to change in a draft spec. Edit: And Safari.)

const sharedWorkerClients = await clients.matchAll({ type: "sharedworker" });
sharedWorkerClients[0].postMessage('Send this message to ???');

So where is the message event dispatched in the shared worker? Or is postMessage() a no-op here?

(There are workarounds like having the document transfer SharedWorker#port to the service worker. I'm wondering if there's a way to send messages directly.)

Ben Dean
  • 21
  • 3
  • 1
    Try to use the Broadcast channel API instead https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel , with `self` instead of `navigator` – NVRM Aug 03 '22 at 16:06
  • Good point about BroadcastChannel! Unfortunately I need to use the second "transferables" parameter to postMessage for my use case, so BroadcastChannel.postMessage doesn't work. – Ben Dean Aug 03 '22 at 16:12
  • Yes, you can transfer only strings via BroadcastChannel `postMessage()`. Btw you can just use JSON.stringify(), and JSON.parse() on the other side? Maybe this can help https://stackoverflow.com/a/53876900/2494754 – NVRM Aug 03 '22 at 16:17

0 Answers0