Is it possible to call a Shared Worker from the Web Worker?
Could you please give me an example.
In my case I have a few web workers and I need to share a singleton service between them.
Is it possible to call a Shared Worker from the Web Worker?
Could you please give me an example.
In my case I have a few web workers and I need to share a singleton service between them.
You can use a technique similar to that at https://stackoverflow.com/a/30796101/1319998 . For each dedicated worker, you can create a shared worker object, pointing to the same script, and pass its port to the dedicated worker.
Note that for the same script URL, new SharedWorker(scriptUrl)
doesn't necessarily create a new shared worker thread: it just creates a new object that allows you to communicate with the shared worker thread, and only creates the thread itself if it doesn't already exist.
As an example, the following creates 2 Worker
objects, that each create a separate dedicated worker thread, and 2 SharedWorker
objects, that in total creates one shared worker thread. The port objects of the shared workers are passed to the dedicated workers:
var sharedWorkerA = new SharedWorker("worker-shared.js");
sharedWorkerA.port.start();
var dedicatedWorkerA = new Worker("worker-dedicated.js");
dedicatedWorkerA.postMessage({sharedWorkerPort: sharedWorkerA.port, workerName: 'A'}, [sharedWorkerA.port]);
var sharedWorkerB = new SharedWorker("worker-shared.js");
sharedWorkerB.port.start();
var dedicatedWorkerB = new Worker("worker-dedicated.js");
dedicatedWorkerB.postMessage({sharedWorkerPort: sharedWorkerB.port, workerName: 'B'}, [sharedWorkerB.port]);
The dedicated workers can then post messages on the port objects they have received:
self.onmessage = function(e) {
var workerName = e.data.workerName;
var sharedWorkerPort = e.data.sharedWorkerPort;
self.setInterval(function() {
sharedWorkerPort.postMessage('sent from dedicated worker ' + workerName);
}, 2000);
};
And the the shared worker can receive them:
var num = 0;
self.onconnect = function(e) {
console.log('shared connect');
var port = e.ports[0];
port.onmessage = function(e) {
num++;
console.log('Received in shared worker: ', e.data);
console.log('Number of messaged received:', num);
};
};
I've put a bit of extra code in there just to show that there is indeed one actual shared worker thread running. You can see the above working at http://plnkr.co/edit/RcxxY2EDIcclUegC82wG?p=preview
The
SharedWorker
constructor is not currently available within theWorkerGlobalScope
, so you will not be able to construct an instance like you would in an iframe or window.What you can do is, create a MessageChannel for each of your workers, and use it to communicate between the worker and sharedWorker. Though doing this would negate the need for an actual
SharedWorker
, since you could just as well use a singleWorker
instead.Example:
Demo