Как позвонить в общий рабочий из веб-работника?

Можно ли вызвать Shared Worker из Web Worker?

Не могли бы вы дать мне пример.

В моем случае у меня есть несколько веб-работников, и мне нужно разделить синглтон-сервис между ними.

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

демонстрация

Вы можете использовать технику, аналогичную описанной на /questions/26163088/nerest-obschego-rabotnika-v-predannom-rabotnike/26163103#26163103. Для каждого выделенного работника вы можете создать общий рабочий объект, указывающий на тот же сценарий, и передать его порт выделенному работнику.

Обратите внимание, что для того же скрипта 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

Другие вопросы по тегам