Search code examples
node.jsmultithreadingthreadpoolworker-thread

How do I create a direct communication channel between two worker threads in Node.js


Is there a way to create a direct communication channel using new MessageChannel between two worker threads? For Eg: There is a main thread P that I have created using the worker_thread API, which creates two worker threads W1 and W2

P -> W1
  -> W2

I want to enable communication between W1 and W2 directly instead of going via P using parentPort.


Solution

  • Use new MessageChannel() to generate a two-way communications channel.

    index.js

    const { Worker } = require('worker_threads');
    
    const path = require('path'); 
    
    const w1 = new Worker(path.join(__dirname,'./worker1.js'));
    const w2 = new Worker(path.join(__dirname,'./worker2.js'));
    
    w1.once('message', value => {
        w2.postMessage({
            port: value.port
        }, [value.port]);
    });
    
    w2.once('message', value => {
        w1.postMessage({
            port: value.port
        }, [value.port]);
    });
    

    worker1.js

    const { MessageChannel, parentPort,  } = require('worker_threads');
    
    let woker2Port;
    console.log('worker1 started');
    
    const { port1, port2 } = new MessageChannel();
    port1.on('message', (value) => {
        console.log(value);
    });
    
    parentPort.postMessage({
        port: port2,
    }, [port2]);
    
    parentPort.on('message', value => {
        if (value.port) {
            woker2Port = value.port;
            woker2Port.postMessage({msg:'i am worker1!'});// send msg to worker2
            return;
        }
    });
    

    worker2.js

    const { MessageChannel, parentPort,  } = require('worker_threads');
    
    let woker1Port;
    console.log('worker2 started');
    
    const { port1, port2 } = new MessageChannel();
    port1.on('message', (value) => {
        console.log(value);
    });
    
    parentPort.postMessage({
        port: port2,
    }, [port2]);
    
    parentPort.on('message', value => {
        if (value.port) {
            woker1Port = value.port;
            woker1Port.postMessage({msg:'i am worker2!'});// send msg to worker1
        }
    });
    

    Notice: if you debug this code in VSCode, you won't see the log print in worker1.js and worker2.js. Run node index directly or debug it in ndb works fine!