Как позвонить в общий рабочий из веб-работника?
Можно ли вызвать 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