Communication between child processes in Node.js

Viewed 7256

I'm trying to make a program in node.js that creates two processes using the fork() method of childproccess. The processes are as follows:

  • Father.js
  • Son1.js
  • Son2.js

I want to transfer data between two child processes directly, not between father and children. I show you a graph of what I'm trying to do.

communication between child proccess

I tried with the following code, but it did not work for me.

In the father.js code, I 'm creating the childs processes as follows:

const cp = require("child_process");
var son1 = cp.fork("${__dirname}/son1.js");
var son2 = cp.fork("${__dirname}/son2.js");

console.log("father sending message to son1..");
son1.send({msg:'Hi son1',br:son2});

console.log("father sending message to son2..");
son2.send({msg:'Hi son1',br:son1});

The Son1.js's code:

var brother=null;
process.on('message', function(json)
{
  console.log('message father in son1.js;', json.msg);
  brother=json.br;
  brother.send("hello I'm son1.js"); 
});

And the Son2.js 's code:

var brother=null;     
process.on('message', function(json)
{     
  console.log('message father in son2.js;', json.msg);       
  brother=json.br;
  brother.send("hello I'm son2.js");         
});

How can I send and receive messages from son1.js to son2.js and vice versa without sending messages to father.js?

3 Answers

Here's what you can do:

  1. Create an IPC server on the parent linked to a socket file.
  2. Open a connection to the server (still within the parent), creating a socket pair.
  3. Send the server's socket to one child, send the client's socket to the other child.

parent.js:

const net = require('net');
const cp = require('child_process');

let u_proc_1 = cp.fork(__dirname+'/child.js', ['#1']);
let u_proc_2 = cp.fork(__dirname+'/child.js', ['#2']);

// create IPC server on parent
let d_server = net.createServer((d_socket_2) => {
    // send server socket to #2
    u_proc_2.send('socket', d_socket_2);
});

// create socket file
let p_socket = __dirname+'/sibling.sock';

// bind server to socket file
d_server.listen(p_socket);

// create client socket; this also triggers creation of a server socket
let d_socket_1 = net.connect(p_socket, () => {
    // have #1 send to #2
    u_proc_1.send('hey!');

    // have #2 send to #1
    u_proc_2.send('hello');
});

// send client socket to #1
u_proc_1.send('socket', d_socket_1);

child.js:

const name = process.argv[2];

let d_socket_sibling;

process.on('message', (s_action, d_socket_msg) => {
    // parent is sending a socket
    if('socket' === s_action) {
        console.log(name+' now has a socket');

        // save socket to variable for later use
        d_socket_sibling = d_socket_msg;

        // receive data from sibling
        d_socket_sibling.on('data', (s_data) => {
            console.log(name+' received: '+s_data);
        });
    }
    // otherwise, parent wants me to send message to sibling
    else {
        console.log(name+' is sending: '+s_action);

        // send data to sibling
        d_socket_sibling.write(s_action);
    }
});

Output:

#2 now has a socket
#1 now has a socket
#2 is sending: hello
#1 is sending: hey!
#1 received: hello
#2 received: hey!

The result is a direct, two-way communication channel between the two child processes, existentially mediated by the parent. Keep in mind that you will have to clean up the socket file somehow (e.g., deleting it on startup or before closing the parent)

Related