Detailed explanation of how two Node.js processes communicate

Detailed explanation of how two Node.js processes communicate

Preface

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

  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 usually used for communication, while for the second scenario, there are two sub-scenarios:

  1. Node.js process communicates with the Node.js child process it created
  2. Node.js process communicates with another unrelated Node.js process

The former can use the built-in IPC communication channel, and the latter can use a custom pipeline, which is described in detail below:

Communication between two Node.js processes on different computers

In order to communicate, we must first figure out how to identify the 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 (process) in the host. In this way, the process of the network can be identified using the triplet (IP address, protocol, port).

Using TCP Sockets

TCP socket is a communication method based on TCP/IP protocol, which allows processes on computers connected through the network to communicate. One is used as server and the other as client. The 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)

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)

Operation effect:

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

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

Using HTTP protocol

Because the HTTP protocol is also based on TCP, from a communication perspective, this method is essentially no different, it just encapsulates the upper-layer protocol. The server.js code is:

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

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()

Operation effect:

$ node server.js
url /hello

$ node client.js
statusCode: 200
hello

Communication between two Node.js processes on the same computer

Although network sockets can also be used for inter-process communication on the same host (through the loopback address 127.0.0.1), this method requires going through the network protocol stack, packaging and unpacking, calculating checksums, maintaining sequence numbers and responses, etc., which is designed for network communication. Two processes on the same computer can have a more efficient communication method, namely IPC (Inter-Process Communication). The specific implementation method on Unix is ​​Unix domain socket, which is a method for communication between the server and the client through a locally opened socket file. Unlike TCP communication, local files are specified during communication, so domain resolution and external communication are not performed, so it is faster than TCP, and the transmission speed on the same host is twice that of TCP.

Using built-in IPC channels

If you want to communicate with a child process you created, it is very convenient. The fork method in the child_process module has its own communication mechanism, so you don't need to pay attention to the underlying details. For example, the parent process parent.js code:

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

Child process child.js code:

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

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

The operation effect is as follows:

$ node parent.js
message from child: hello
message from parent: hi
message from child: hello
message from parent: hi

Using a custom pipeline

If there are two independent Node.js processes, how to establish a communication channel? On Windows, you can use named pipes (Named PIPE), and on Unix, you can use unix domain sockets, one as the server and the other as the client. The server.js code is as follows:

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)

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)

Operation effect:

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

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

Summarize

This is the end of this article about how two Node.js processes communicate. For more information about how two Node.js processes communicate, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of learning parent-child process communication from Node.js child_process module
  • Node uses process communication to implement Cluster shared memory

<<:  How to solve the problem of insufficient permissions when switching users in docker container

>>:  Limit HTML text box input to only numbers and decimal points

Recommend

Pure CSS to achieve input box placeholder animation and input verification

For more exciting content, please visit https://g...

MySQL multi-instance installation boot auto-start service configuration process

1.MySQL multiple instances MySQL multi-instance m...

A general method for implementing infinite text carousel with native CSS

Text carousels are very common in our daily life....

Centering the Form in HTML

I once encountered an assignment where I was give...

How to implement horizontal bar chart with percentage in echarts

Table of contents Example Code Rendering Code Ana...

Analysis of the use of the MySQL database show processlist command

In actual project development, if we have a lot o...

JavaScript implements the nine-grid mobile puzzle game

This article shares the specific code for JavaScr...

MySQL learning record: bloody incident caused by KEY partition

Demand background Part of the data in the busines...

Design Tips: We think you will like it

<br />Looking at this title, you may find it...

How to use Zen coding in Dreamweaver

After I published my last article “Zen Coding: A Q...

The best solution for implementing digital plus and minus buttons with pure CSS

Preface: For the implementation of digital additi...

Example code for converting http to https using nginx

I am writing a small program recently. Because th...