🔌

Unix domain socket with Node.js

に公開

この記事内のコードはGithubにもあります。コードだけ見たい場合は↓から飛んでいってください。

https://github.com/ruka-64/nodejs-unix-sock-test

はじめに

別のサーバーとやり取りするためにlocalhost:3000/apiへリクエストを送りつけるとか、無駄ですよね?
プロセス間通信ができれば、無駄なくやり取りをすることができます。今回はUnixドメインソケットを使ってそれっぽい事をやってみようというわけです。

ここら辺の仕組みはさっぱりでノリにまかせてやっているので、こうしろあーしろ等あればコメントへ...

サーバー側

サーバーの立ち上げはこれだけで済みます。
クライアントから送られてきたデータをそっくりそのまま返してくれます。

import { unlinkSync } from 'fs';
import net from 'net';

const SOCK_PATH = 'test.sock'; // ./test.sock

// サーバー作成
const server = net.createServer((conn) => {
  // 新規接続時の処理
  console.log('Connected.');
  conn.on('close', () => console.log('disconnected'));
  conn.on('data', (data) => {
    console.log('[data]', data.toString());
    conn.write(data); // echo
    return;
  });
  conn.on('error', (err) => console.error('[err]', err));
});

server.listen(SOCK_PATH);

このままでもいいですが、終了処理も加えてみましょう。この時作成されるtest.sockは勝手に消えてくれないので、次の起動時に存在するとエラーが出てしまいます。

とはいえそこまで難しいわけでもなく、これだけで済みます。

const end = () => {
  try {
    console.log('Shutting down...');
    unlinkSync(SOCK_PATH);
    console.log('Bye');
    process.exit(0);
  } catch (e) {
    console.error(e);
    process.exit(1);
  }
};

process.on('SIGINT', end);
process.on('SIGTERM', end);

クライアント側

1秒おきにメッセージを送りつけます。

import net from 'net';

const SOCK_PATH = 'test.sock'; // ./test.sock

const client = net.createConnection(SOCK_PATH);

client.on('connect', () => {
  console.log('connected');
});
client.on('data', (data) => {
  console.log(data.toString());
});
client.on('end', () => {
  console.log('disconnected.');
});
client.on('error', (err) => {
  console.error('[err]', err.message);
});

let i = 0;
setInterval(() => {
  client.write(`Count is ${i}`);
  i++;
}, 1000);

超シンプルです。
こいつもいじくってみましょう。例えばサーバーが立ち上がってなかったときはソケットファイルが見つからずにENOENTエラーを吐きますが、そのままプロセスが停止してくれません。
なのでこうします:

client.on('error', (err) => {
+ if (err.message.startsWith('connect ENOENT')) {
+   console.log("Cannot find socket (server.js isn't running?");
+   process.exit(1);
+ }
  console.error('[err]', err.message);
});

やっぱりJavaScriptなので、簡単にこういう事もできちゃいます。

おわり!

Discussion