admin管理员组

文章数量:1322036

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.

Share Improve this question asked Jun 14, 2015 at 13:34 WarlockWarlock 7,48110 gold badges56 silver badges75 bronze badges 3
  • possible duplicate of Spawning a Shared Worker in a Dedicated Worker – Michal Charemza Commented Jun 14, 2015 at 14:58
  • @MichalCharemza that will not work for multiple dedicated workers, since the port object can only be transferred once. – levi Commented Jun 14, 2015 at 15:04
  • For each dedicated worker, you can created a new SharedWorker, and pass the port object to it. However, I see that the answer you're looking for is a bit different to that at stackoverflow./a/30796101/1319998 . Removing my close vote... – Michal Charemza Commented Jun 14, 2015 at 15:19
Add a ment  | 

2 Answers 2

Reset to default 7

You can use a technique similar to that at https://stackoverflow./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 municate 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 the WorkerGlobalScope, 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 municate between the worker and sharedWorker. Though doing this would negate the need for an actual SharedWorker, since you could just as well use a single Worker instead.

Example:

var numWorkers = 4;
var sharedWorker = new Worker("worker-shared.js");

for(var i = 0; i < numWorkers; i++) {
  var dedicatedWorker = new Worker("worker-dedicated.js");
  var channel = new MessageChannel();
  dedicatedWorker.postMessage({sharedWorkerPort: channel.port1}, [channel.port1]);
  sharedWorker.postMessage({workerPort: channel.port2}, [channel.port2]);
}

Demo

本文标签: javascriptHow to call shared worker from the web workerStack Overflow