How do two Node.js processes communicate with each other? There are two scenarios:

  1. Communication between two Node.js processes on different computers
  2. Communication between two Node.js processes on the same computer

For the first scenario, TCP or HTTP is typically used for communication, while for the second scenario, there are two sub-scenarios:

  1. Node.js processes communicate with the Node.js child processes they create
  2. Node.js processes communicate with unrelated Node.js processes

The former can use the built-in IPC communication channel, while the latter can use custom pipes, which are described in detail below:

Communication between two Node.js processes on different computers

To communicate, you first have to figure out how to identify processes in the network. The IP address of the network layer can uniquely identify the host in the network, while the protocol and port of the transport layer can uniquely identify the application program (process) in the host. In this way, the process of the network can be identified by triples (IP address, protocol, and port).

Use TCP sockets

TCP sockets are a communication method based on THE TCP/IP protocol. They enable processes on computers connected through the network to communicate with each other. One as a server and the other as a client, server.js code is as follows:

const net = require('net')
const server = net.createServer(socket= > {
  console.log('socket connected')
  socket.on('close'.() = > console.log('socket disconnected'))
  socket.on('error'.err= > console.error(err.message))
  socket.on('data'.data= > {
    console.log(`receive: ${data}`)
    socket.write(data)
    console.log(`send: ${data}`)
  })
})
server.listen(8888)
Copy the code

Client. Js code:

const net = require('net')
const client = net.connect(8888.'192.168.10.105')

client.on('connect'.() = > console.log('connected.'))
client.on('data'.data= > console.log(`receive: ${data}`))
client.on('end'.() = > console.log('disconnected.'))
client.on('error'.err= > console.error(err.message))

setInterval(() = > {
  const msg = 'hello'
  console.log(`send: ${msg}`)
  client.write(msg)
}, 3000)
Copy the code

Operation effect:

$ node server.js
client connected
receive: hello
send: hello

$ node client.js
connect to server
send: hello
receive: hello
Copy the code

Using HTTP

Since the HTTP protocol is also based on TCP, this approach is essentially the same from a communications point of view, just encapsulating the upper-layer protocol. The server.js code is:

const http = require('http')
http.createServer((req, res) = > res.end(req.url)).listen(8888)
Copy the code

Client. Js code:

const http = require('http')
const options = {
  hostname: '192.168.10.105'.port: 8888.path: '/hello'.method: 'GET',}const req = http.request(options, res= > {
  console.log(`statusCode: ${res.statusCode}`)
  res.on('data'.d= > process.stdout.write(d))
})
req.on('error'.error= > console.error(error))
req.end()
Copy the code

Operation effect:

$ node server.js
url /hello

$ node client.js
statusCode: 200
hello
Copy the code

Communication between two Node.js processes on the same computer

Although network sockets can also be used for interprocess communication on the same host (using loopback address 127.0.0.1), this method is designed for network communication by going through the network protocol stack, packing and unpacking, calculating checksums, maintaining serial numbers and answering, etc. Two processes on the same computer can have a more efficient Communication mode, namely inter-process Communication (IPC). On Unix, the specific implementation mode is Unix Domain socket. This is a method of communication between the server and the client through a socket file opened locally. Unlike TCP communication, local files are specified during communication, so domain resolution and external communication are not carried out, so the transmission speed is faster than TCP and twice as fast as TCP on the same host.

Use the built-in IPC channel

The fork method in the child_process module has its own communication mechanism and does not need to pay attention to the low-level details, such as the parent process parent-js code:

const fork = require("child_process").fork
const path = require("path")
const child = fork(path.resolve("child.js"), [] and {stdio: "inherit" });
child.on("message".(message) = > {
  console.log("message from child:", message)
  child.send("hi")})Copy the code

Child process child.js code:

process.on("message".(message) = > {
  console.log("message from parent:", message);
})

if (process.send) {
  setInterval(() = > process.send("hello"), 3000)}Copy the code

The running effect is as follows:

$ node parent.js
message from child: hello
message from parent: hi
message from child: hello
message from parent: hi
Copy the code

Use custom pipes

If there are two separate Node.js processes, how do you set up a communication channel? On Windows you can use Named PIPE, and on Unix you can use Unix Domain sockets, also one as server and one as client. Server.js:

const net = require('net')
const fs = require('fs')

const pipeFile = process.platform === 'win32' ? '\\\\.\\pipe\\mypip' : '/tmp/unix.sock'

const server = net.createServer(connection= > {
  console.log('socket connected.')
  connection.on('close'.() = > console.log('disconnected.'))
  connection.on('data'.data= > {
    console.log(`receive: ${data}`)
    connection.write(data)
    console.log(`send: ${data}`)
  })
  connection.on('error'.err= > console.error(err.message))
})

try {
  fs.unlinkSync(pipeFile)
} catch (error) {}

server.listen(pipeFile)

Copy the code

The client.js code is as follows:

const net = require('net')

const pipeFile = process.platform === 'win32' ? '\\\\.\\pipe\\mypip' : '/tmp/unix.sock'

const client = net.connect(pipeFile)
client.on('connect'.() = > console.log('connected.'))
client.on('data'.data= > console.log(`receive: ${data}`))
client.on('end'.() = > console.log('disconnected.'))
client.on('error'.err= > console.error(err.message))

setInterval(() = > {
  const msg = 'hello'
  console.log(`send: ${msg}`)
  client.write(msg)
}, 3000)

Copy the code

Operation effect:

$ node server.js 
socket connected.
receive: hello
send: hello

$ node client.js
connected.
send: hello
receive: hello
Copy the code