Komunikacja pracowników sieci za pomocą MessageChannel HTML5

Chciałbym wdrożyć komunikację między webworkerami. Przeczytałem dokumentację W3C i znalazłem MessageChannel jest jednym ze sposobów, aby to zrobić, ale czytając MessageChannel nie mogłem zrozumieć, jak zaimplementować komunikację między pracownikami za pomocą messagechannel.

Dostałem to z MSDN

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

Tutaj również nie ma odpowiedniej dokumentacji, aby to zrobić.

Muszę wiedzieć, jak czy mogę komunikować się z webworkerami za pomocą MessageChannel?

Oto 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("");

    })

I pracownik

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);
}
Author: Konga Raju, 2013-01-07

3 answers

Oto czysty przykład w czystym javascript, jak skonfigurować to między dwoma robotami:

W głównym wątku:

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

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

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

To pokazuje, jak obsługiwać wiadomości z głównego wątku, jak możesz przekazywać wiadomości z głównego wątku do drugiego pracownika i jak komunikować się między pracownikami bezpośrednio bez udziału głównego wątku.

 10
Author: Wilt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-10 14:17:07

Twoje demo faktycznie działa dla mnie (Chrome 23.0.1271.101). Dostaję DATA_CLONE_ERR tylko wtedy, gdy nacisnę drugi przycisk "Wyślij do subworker". Prawdopodobnie tego się oczekuje. Wysłałeś już port2 swojego MessageChannel do pracownika z pierwszym postMessage wywołaniem zaraz po utworzeniu kanału. To prawdopodobnie nielegalne, aby wysłać go ponownie, choć nie mogę znaleźć żadnej wyraźnej dokumentacji na ten temat.

To, co prawdopodobnie chcesz zrobić, to ustawić onmessage na porcie odbieranym w workerze, wtedy możesz obsłużyć wiadomości wysyłane przez port w przyszłości. Coś w stylu:

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
}
 3
Author: Nik Haldimann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-08 02:50:40

Po pewnym czasie pracy nad MessageChannel API. Mam rozwiązanie do komunikacji webworkerów za pomocą MessageChannel. Oto Demo roboczego kodu.

 0
Author: Konga Raju,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 07:27:05