Search code examples
javascriptweb-worker

Sending messages from SharedWorker to SharedWorker


The MDN Documentation on SharedWorkers states:

The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers.

To me this sounds as if SharedWorkers should be able to directly exchange messages. However, if I try to access a SharedWorker from within another SharedWorker, namely with

var worker = new SharedWorker("path/to/file.js");

I get

ReferenceError: SharedWorker is not defined

Did I just misread the documentation, or is there another way to do this?


Solution

  • Although you don't seem to be able to create a shared worker from a shared worker, you can communicate between them by creating them in the main thread, and passing the MessagePort object of one to the other. Note you have to include the port in the transfer list argument to postMessage: it can't be copied.

    For example, in the main thread create the workers, and send the port of one to the other:

    var myWorker1 = new SharedWorker("worker1.js");
    myWorker1.port.start();
    
    var myWorker2 = new SharedWorker("worker2.js");
    myWorker2.port.start();
    
    myWorker2.port.postMessage({worker1Port: myWorker1.port}, [myWorker1.port]);
    

    In the first worker you can send messages on a port:

    self.onconnect = function(e) {
      var port = e.ports[0];
    
      self.setInterval(function() {
        port.postMessage('sent from worker 1');
      }, 1000);
    };
    

    and then in the second worker you can save the incoming port object, and respond to messages received on it.

    self.onconnect = function(e) {
      var port = e.ports[0];
    
      port.onmessage = function(e) {
        var worker1Port = e.data.worker1Port;
        worker1Port.onmessage = function(e) {
          console.log('received in worker 2', e.data);
        };
      };
    };
    

    You can see this working at http://plnkr.co/edit/XTOej1b1PHfWuC9LHeZc?p=preview