samedi 3 octobre 2020

How to share data with SharedWorker

There has been a lot of discussions and tutorials on SharedWorker on the Internet and StackOverflow, but none has really achieved the most basic goal -- passing data directly between two shared workers.

To me, the strength of SharedWorker over a dedicated web Worker is that the former allows direct communication over different tabs, iframes and threads. I tried the following:

(shared.html:)

<!DOCTYPE html><html><head></head><body>
<button onclick="init('a')">Initiate A</button>
<button onclick="init('b')">Initiate B</button>
<script>

var a,b;
function init(v) {
    if (v=='a'){
        a = (new SharedWorker('./shared.js')).port;
        a.start();
        a.postMessage({type:'start', port:b})
    } else {
        b = (new SharedWorker('./shared.js')).port;
        b.start();
        b.postMessage({type:'start', port:a});    // <== error here
    }
}

</script></body></html>

(shared.js)

let peer = null;

onconnect = function (ev) {
    let port = ev.ports[0];
    port.onmessage = (e) => {
        if (e.data.type=='start' && e.data.port){
            peer=e.data.port;
        } else if (e.data.type=='msg' && peer){
            setInterval(()=>{
                peer.postMessage({type:'msg',msg:'greetings!'});
            },2000);
        }
    }
    port.start();
}

After clicking 'Initiate A' and then 'Initiate B', I got the following error message on the console:

shared.html:15 Uncaught DOMException: Failed to execute 'postMessage' on 'MessagePort': A MessagePort could not be cloned because it was not transferred.

In other words, I couldn't pass the ports around.

So is SharedWorker of any use at all. It seems that the regular dedicated Worker suffices under most circumstances.




Aucun commentaire:

Enregistrer un commentaire