15

Webworker間のコミュニケーションを実装したいと思います。W3Cのドキュメントを読んだところ、MessageChannelがその方法の1つであることがわかりましたが、MessageChannelを読んでいる間、messagechannelを使用してワーカー間の通信を実装する方法を理解できませんでした。

これはMSDNから入手しました

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

これを行うための適切なドキュメントもありません。

MessageChannelを使用してWebワーカーと通信するにはどうすればよいですか?

これが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("");

    })

と労働者

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

3 に答える 3

13

2 つのワーカー間でこれを設定する方法に関する純粋な JavaScript のクリーンな例を次に示します。

メインスレッドで:

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

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

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

これは、メイン スレッドからのメッセージを処理する方法、メイン スレッドから他のワーカーにメッセージを転送する方法、およびメイン スレッドを介さずに直接ワーカー間で通信する方法を示しています。

于 2015-12-10T09:49:27.197 に答える
3

あなたのデモは実際に私のために機能します(Chrome 23.0.1271.101)。2番目の「サブワーカーに送信」ボタンを押した場合にのみ、DATA_CLONE_ERRを取得します。これはおそらく予想されます。チャネルを作成した直後に、最初の呼び出しでワーカーに既に送信port2しています。再度送信することはおそらく違法ですが、これに関する明示的なドキュメントも見つかりません.MessageChannelpostMessage

おそらくやりたいことはonmessage、ワーカーで受信したポートに設定することです。そうすれば、将来、ポートを介して送信されたメッセージを処理できます。何かのようなもの:

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
}
于 2013-01-08T02:50:40.257 に答える
1

MessageChannel APIでしばらく作業した後。MessageChannel を使用して Webworker と通信するためのソリューションを取得しました。ここに作業コードのデモがあります。

于 2013-01-08T11:47:23.857 に答える