How to call shared worker from the web worker?

走远了吗. 提交于 2019-12-03 17:07:47

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 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 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

Michal Charemza

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!