NodeJS UNIX Sockets

Home / NodeJS UNIX Sockets

NodeJS UNIX Sockets

December 9, 2015 | Article | No Comments

UNIX socket or Unix domain socket, also known as IPC socket (inter-process communication socket) is a data communications endpoint for exchanging data between processes executing within the same host operating system. The similar functionality used by named pipes, but Unix domain sockets may be created as connection-mode or as connectionless.

Unix domain sockets use the file system as their address name space. They referenced by process as inodes in the file system. This allows two processes to open the same socket in order to communicate. However, communication occurs entirely within the operating system kernel.

Server

Node’s net.Server class not only supports TCP sockets, but also UNIX domain sockets.

To create a UNIX socket server, we have to create a normal net.Server bu then make it listen to a file path instead of a port.

var server = net.createServer(function(socket) {
    // got a client connection here
});
server.listen('/path/to/socket');

UNIX domain socket servers present the exact same API as TCP server.

If you are doing inter-process communication that is local to host, consider using UNIX domain sockets instead of TCP sockets, as they should perform much better. For instance, when connecting node to a front-end web-server that stays on the same machine, choosing UNIX domain sockets is generally preferable.

Client

Connecting to a UNIX socket server can be done by using net.createConnection as when connecting to a TCP server. The difference is in the argument, a socket path is passed in instead of a port.

var net = require('net');
var conn = net.createConnection('/path/to/socket');
conn.on('connect', function() {
    console.log('connected to unix socket server');
});

Passing File Descriptors Around

UNIX sockets have this interesting feature that allows us to pass file descriptors from a process into another process. In UNIX, a file descriptor can be a pointer to an open file or network connection, so this technique can be used to share files and network connections between processes.
For instance, to grab the file descriptor from a file read stream we should use the fd attribute like this:

var fs = require('fs');
var readStream = fs.createReadStream('/etc/passwd', {flags: 'r'});
var fileDescriptor = readStream.fd;

and then we can pass it into a UNIX socket using the second or third argument of socket.write like this:

var socket = ...
// assuming it is UTF-8
socket.write('some string', fileDescriptor);

// specifying the encoding
socket.write('453d9ea499aa8247a54c951', 'base64', fileDescriptor);

On the other end, we can receive a file descriptor by listening to the “fd” event like this:

var socket = ...
socket.on('fd', function(fileDescriptor) {
    // now I have a file descriptor
});

We can do various Node API operation, depend on the type of file descriptor.

Read or Write into File

If it’s a file-system file descriptor, we can use the Node low-level “fs” module API to read or write data.

var fs = require('fs');
var socket = ...
socket.on('fd', function(fileDescriptor) {
    // write some
    var writeBuffer = new Buffer("here is my string");
    fs.write(fileDescriptor, writeBuffer, 0, writeBuffer.length);

    // read some
    var readBuffer = new Buffer(1024);
    fs.read(fileDescriptor, readBuffer, 0, readBuffer.length, 0,
    function(err, bytesRead) {
        if (err) {console.log(err); return; }
        console.log('read ' + bytesRead + ' bytes:');
        console.log(readBuffer.slice(0, bytesRead));
    });
});

We should be careful because of the file open mode. If the is opened with “r” flag, no write operation can be done.

Listen to the Server Socket

As another example on sharing a file descriptor between processes: if the file descriptor is a server socket that was passed in, we can create a server on the receiving end and associate the new file descriptor by using the server.listenFD method on it to it like this:

var server = require('http').createServer(function(req, res) {
    res.end('Hello World!');
});

var socket = ...
socket.on('fd', function(fileDescriptor) {
    server.listenFD(fileDescriptor);
});

We can use listenFD() on an “http” or “net” server. In fact, on anything that descends from net.Server.

, ,

About Author

about author

xathrya

A man who is obsessed to low level technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

Social media & sharing icons powered by UltimatelySocial