最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Web Workers communication using MessageChannel HTML5 - Stack Overflow

programmeradmin4浏览0评论

I would like to implement communication between webworkers. I read the W3C documentation and I found MessageChannel is one of the ways to do it, but while reading MessageChannel I couldn't understand how to implement communication between workers using messagechannel.

I got this from MSDN

(v=vs.85).aspx

Here is also no proper documentation to do it.

I need to know, how can I communicate webworkers using MessageChannel?

Here is the Demo throwing DATA_CLONE_ERR

var worker = new Worker("sub1_worker.js");
    worker.onmessage = function(e) {
        $("#log").append("<br>" + e.data);
    }
    var channel = new MessageChannel();

    worker.postMessage("ping", [channel.port2]);

    channel.port1.onmessage = function(event) {
        // Message is in event.data
        alert("Message is: " + event.data);
    }

    channel.port1.postMessage('hello');



    $("#send1").click(function() {
        var msg = $("#msg").val();
        if (msg && msg != "start")
            worker.postMessage("ping2");

        $("#msg").val("");

    })
    $("#send2").click(function() {
        var msg = $("#msg").val();
        if (msg && msg != "start")
            worker.postMessage("ping3",[channel.port2]);
        $("#msg").val("");

    })

and worker

onmessage = getMessage;

function getMessage(e){

    if(e.ports[0])
    e.ports[0].postMessage("msg from sub worker 1 "+ e.data);
    else
    postMessage("msg from sub worker 1 "+ e.data);
}

I would like to implement communication between webworkers. I read the W3C documentation and I found MessageChannel is one of the ways to do it, but while reading MessageChannel I couldn't understand how to implement communication between workers using messagechannel.

I got this from MSDN

http://msdn.microsoft.com/en-in/library/ie/hh673525(v=vs.85).aspx

Here is also no proper documentation to do it.

I need to know, how can I communicate webworkers using MessageChannel?

Here is the Demo throwing DATA_CLONE_ERR

var worker = new Worker("sub1_worker.js");
    worker.onmessage = function(e) {
        $("#log").append("<br>" + e.data);
    }
    var channel = new MessageChannel();

    worker.postMessage("ping", [channel.port2]);

    channel.port1.onmessage = function(event) {
        // Message is in event.data
        alert("Message is: " + event.data);
    }

    channel.port1.postMessage('hello');



    $("#send1").click(function() {
        var msg = $("#msg").val();
        if (msg && msg != "start")
            worker.postMessage("ping2");

        $("#msg").val("");

    })
    $("#send2").click(function() {
        var msg = $("#msg").val();
        if (msg && msg != "start")
            worker.postMessage("ping3",[channel.port2]);
        $("#msg").val("");

    })

and worker

onmessage = getMessage;

function getMessage(e){

    if(e.ports[0])
    e.ports[0].postMessage("msg from sub worker 1 "+ e.data);
    else
    postMessage("msg from sub worker 1 "+ e.data);
}
Share Improve this question edited Jan 7, 2013 at 10:09 kongaraju asked Jan 7, 2013 at 7:07 kongarajukongaraju 9,59611 gold badges57 silver badges78 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 14

Here a clean example in pure javascript on how to set this up between two workers:

In main thread:

function setup(){
    var channel = new MessageChannel();
    var worker1 = new Worker("worker1.js");
    var worker2 = new Worker("worker2.js");

    // Setup the connection: Port 1 is for worker 1
    worker1.postMessage({
        command : "connect",
    },[ channel.port1 ]);

    // Setup the connection: Port 2 is for worker 2
    worker2.postMessage({
        command : "connect",
    },[ channel.port2 ]);

    worker1.postMessage({
        command: "forward",
        message: "this message is forwarded to worker 2"
    });
}

In worker1.js:

var worker2port;
var onMessageFromWorker2 = function( event ){
    console.log("Worker 1 received a message from worker 2: " + event.data);

    //To send something back to worker 2
    //worker2port.postMessage("");
};

self.onmessage = function( event ) {
    switch( event.data.command )
    {
        // Setup connection to worker 2
        case "connect":
            worker2port = event.ports[0];
            worker2port.onmessage = onMessageFromWorker2;
            break;

        // Forward messages to worker 2
        case "forward":
            // Forward messages to worker 2
            worker2port.postMessage( event.data.message );
            break;

        //handle other messages from main
        default:
            console.log( event.data );
    }
};

In worker2.js

var worker1port;
var onMessageFromWorker1 = function( event ){
    console.log("Worker 2 received a message from worker 1: " + event.data);

    //To send something back to worker 1
    //worker1port.postMessage("");
};

self.onmessage = function( event ) {
    switch( event.data.command )
    {
        // Setup connection to worker 1
        case "connect":
            worker1port = event.ports[0];
            worker1port.onmessage = onMessageFromWorker1;
            break;

        // Forward messages to worker 1
        case "forward":
            // Forward messages to worker 1
            worker1port.postMessage( event.data.message );
            break;

        //handle other messages from main
        default:
            console.log( event.data );
    }
};

This shows to how to handle messages from main thread, how you can forward messages from the main thread to the other worker and how to communicate between the workers directly without the main thread being involved.

Your demo actually works for me (Chrome 23.0.1271.101). I only get the DATA_CLONE_ERR if I hit the second "send to subworker" button. This is probably expected. You already sent port2 of your MessageChannel to the worker with your first postMessage call right after you created the channel. It's probably illegal to send it again, though I can't find any explicit documentation about this either.

What you likely want to do is set onmessage on the port received in the worker, then you can handle messages sent through the port in the future. Something like:

onmessage = getMessage;

function getMessage(e){
  if(e.ports[0]) {
    var receivedPort = e.ports[0];
    receivedPort.postMessage("msg from sub worker 1 "+ e.data);
    receivedPort.onmessage = getPortMessage
  }
  else
    postMessage("msg from sub worker 1 "+ e.data);
}

function getPortMessage(e) {
  // Messages sent through the port will be handled here
}
发布评论

评论列表(0)

  1. 暂无评论