Notice: Expect this repository to be archived
Unix domain sockets for Node.js with support for passing file descriptors between processes.
usocket2 provides UServer and USocket classes that follow the familiar net.Server and net.Socket model while adding Unix descriptor passing. The native addon is built with node-addon-api, and the public wrapper is written in TypeScript.
- Node.js 18 or newer
- A Unix-like operating system
- A working C++ compiler and Python installation for
node-gyp
npm install @cathodique/usocket2When working from a checkout:
npm install
npm testnpm test compiles the TypeScript wrapper, builds the native addon, and runs the test suite.
const fs = require("node:fs");
const usocket = require("usocket");
const path = "/tmp/usocket-example.sock";
const server = new usocket.UServer();
const client = new usocket.USocket();
server.listen(path, () => {
client.connect(path);
});
server.on("connection", (connection) => {
const fd = fs.openSync(__filename, "r");
connection.end({
data: Buffer.from("message"),
fds: [fd],
callback: () => fs.closeSync(fd),
});
});
client.on("connected", () => client.read(0));
client.on("readable", () => {
const message = client.read(7, 1);
if (!message) return;
fs.closeSync(message.fds[0]);
client.end();
server.close();
});UServer is an event emitter that accepts Unix domain socket connections.
Creates a server.
Starts listening on path. The default backlog is 16. The callback is attached to the listening event.
An options object is also supported:
server.listen({ path: "/tmp/example.sock", backlog: 16 }, callback);listening: the socket is ready.connection: receives aUSocketfor each accepted connection.error: reports a socket or operating-system error.
Pause or resume accepting new connections.
Closes the listening socket. Accepted connections are not tracked by the server and must be closed separately.
USocket extends Node.js Duplex. It can send and receive both buffers and Unix file descriptors.
Creates a socket. The constructor can connect immediately when given either a path or an existing descriptor:
new usocket.USocket("/tmp/example.sock");
new usocket.USocket({ fd: existingFd });The callback is attached to the connected event.
Connects to a Unix socket path, or adopts an existing file descriptor:
socket.connect("/tmp/example.sock", callback);
socket.connect({ fd: existingFd }, callback);connected: the socket connection is ready.readable: data or file descriptors are available to read.fds: file descriptors were received. The event argument is an array of numbers.error: an operating-system or socket error occurred.close: the socket is fully closed.end: the peer has finished sending.
Uses the normal readable-stream behavior and returns a Buffer or null.
When the second argument is provided, returns both data and descriptors:
const result = socket.read(7, 1);
// { data: <Buffer ...>, fds: [number] }The call returns null until both the requested data and descriptor count are available. Use null for fdCount to read all currently available descriptors. A descriptor count of zero is valid.
Places data, and optionally file descriptors, back at the front of the readable stream.
Sends a buffer.
Sends an array of file descriptor numbers. Keep the descriptors open until the write callback runs.
Sends data and descriptors together:
socket.write({
data: Buffer.from("message"),
fds: [fd],
callback: () => fs.closeSync(fd),
});The options object supports:
data(Buffer, optional): bytes to send.fds(number[], optional): descriptors to pass.callback(function, optional): called after the complete write finishes.
Optionally writes final data, then shuts down the socket's sending side. The peer receives end after all sent data has been delivered.
Closes the socket immediately. No further socket data can be sent or received.
The repository contains a TypeScript public wrapper in src/index.ts and a C++ native addon in src/uwrap.cc.
npm run build:js # compile TypeScript to dist/
npm run build # build the native addon with node-gyp
npm test # run both builds and the testsThe native implementation uses node-addon-api; NAN is not required.