【问题标题】:How to call shared worker from the web worker?如何从网络工作者调用共享工作者?
【发布时间】:2015-06-14 13:34:27
【问题描述】:

是否可以从 Web Worker 调用 Shared Worker?

你能举个例子吗?

就我而言,我有几个网络工作者,我需要在他们之间共享一个单例服务。

【问题讨论】:

标签: javascript web-worker shared-worker


【解决方案1】:

您可以使用类似于 https://stackoverflow.com/a/30796101/1319998 的技术。对于每个专用工作人员,您可以创建一个共享工作人员对象,指向同一个脚本,并将其端口传递给专用工作人员。

请注意,对于同一个脚本 URL,new SharedWorker(scriptUrl) 并不一定会创建一个新的共享工作线程:它只是创建一个允许您与共享工作线程通信的新对象,并且如果它只创建线程本身尚不存在。

例如,以下创建 2 个 Worker 对象,每个对象创建一个单独的专用工作线程,以及 2 个 SharedWorker 对象,总共创建一个共享工作线程。共享工作者的端口对象被传递给专用工作者:

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]);

然后,专门的工作人员可以在他们收到的端口对象上发布消息:

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);
};

共享工作者可以接收它们:

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);
  };
};

我在其中添加了一些额外的代码,只是为了表明确实有一个实际的共享工作线程正在运行。你可以在http://plnkr.co/edit/RcxxY2EDIcclUegC82wG?p=preview看到上面的工作

【讨论】:

    【解决方案2】:

    SharedWorker 构造函数当前在WorkerGlobalScope 中不可用,因此您将无法像在 iframe 或窗口中那样构造实例。

    您可以做的是,为您的每个工作人员创建一个MessageChannel,并使用它在工作人员和 sharedWorker 之间进行通信。尽管这样做会消除对实际SharedWorker 的需求,因为您也可以使用单个Worker

    例子:

    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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2021-08-07
    • 2011-01-20
    • 1970-01-01
    • 2016-12-13
    • 2015-03-16
    相关资源
    最近更新 更多