This tutorial explores the world of inter-process communication (IPC) in Unix, and solutions for Node developers. IPC actually covers a broad swathe of methods, including POSIX signals and pipes, which we’ve already covered in this series. Here I’m only going to cover IPC methods that are based on sockets or Unix domain sockets.
IPC enables structured data to be shared between processes. In terms of architecture, scaling software by creating smaller programs that communicate with each other using simple data formats fits in with the Unix philosophies mentioned previously in this series. Additionally, it may be desirable to use established Unix-based IPC systems from within Node.
Beyond modularity and performance, IPC can also be used to restrict privileged access to certain resources. For example, a Node web application could run on a registered port (above 1023) which is generally accessible by ordinary user accounts. Then another program with additional privileges to access port 80 could proxy requests to it, thereby limiting access and potentially improving security.
It’s likely that contemporary developers that don’t come from a Unix background will already use IPC and RPC. Message queues in particular are very popular now – ZeroMQ can be configured to communicate locally using its IPC transport that’s based on Unix domain sockets
D-Bus supports many POSIX operating systems. It’s most closely associated with KDE, but can be installed on Mac OS, and there’s even a Windows port. It can use Unix or IP sockets.
D-Bus generally runs as a system-level daemon, and also as a session daemon:
A GNOME environment normally runs two kinds of buses: a single system bus for miscellaneous system-wide communication, e.g. notifications when a new piece of hardware is hooked up; and a session bus used by a single user’s ongoing GNOME session.
The two most popular Node implementations are node-dbus (License: MIT, npm: dbus) by Shouqun Liu, and node-dbus (License: BSD, npm: node-dbus) from Motorola Mobility. They’re both built using C++ extensions that wrap around the libdbus APIs.
It’s unlikely that D-Bus is (or will be) a popular solution for IPC with Node developers, but it does allow us to integrate more tightly with desktop environments. For example, if I use a GNOME music player that exposes services through D-Bus, I could write Node scripts that monitor what I’m listening to and post the data to Last.fm. Linux Journal has a general article on this topic that serves as a basic introduction: Control Your Linux Desktop with D-Bus.
Homegrown IPC and RPC
There are dozens of modules that provide IPC and RPC solutions that are aimed at Node developers without integrating with existing high-level Unix daemons.
DNode by James Halliday is one such example that works with Unix domain sockets, TCP streams, or WebSocket. It’s an RPC implementation that uses a newline-terminated JSON protocol which is documented in the dnode-protocol module.
There’s also thintalk (License: MIT, npm: thintalk) by Andreas Madsen that implements a lightweight RPC layer. It’s aimed at pure Node environments, unlike DNode which can be called from different programming languages and browsers.
ØMQ runs on Linux, Windows, and Mac OS, and specifically targets fast performance. In contemporary discussions on IPC, it’s often cited as a suitable alternative to legacy message brokers.
IPC is an incredibly broad term that covers using files for communication, signals, sockets, message queues, pipes, shared memory, and pretty much everything else. I’m still searching for a quantum-entanglement IPC solution for Unix.
It’s therefore difficult to keep this discussion focused on Unix, particularly as modern systems like ØMQ will run just about anywhere. However, I hope that by mentioning D-Bus, Node hackers who run desktop systems like KDE or GNOME might be inspired to rewire their desktops in all kinds of creative ways.