ファイナンス、情報通信技術のスキル・アグリゲーション・サイト
Node.js で WebSocket サーバーを構築するためのパッケージはいくつかありますが、このページでは、WebSocket パッケージのひとつ ws.js を利用した例を取り上げます。さらに、WebSocket(ws://)と Secure WebSocket(wss://)の接続に、それぞれ http.js と https.js も使用します。なお、今回の内容に、ウェブフレームワークの express.js は必須ではありませんが、組み入れています。
ws - npm の Usage examples には、いくつものコード例かあり、そのままでも、あるいは組み合わせると、大抵のことはできそうです。今回は、External HTTP/S server の例と Server broadcast の例をベースにして Secure WebSocket サーバーを、そして、Sending and receiving text data の例からテスト用クライアントを作成します。
まずは、かんたんに Node.js とパッケージ管理の npm のインストールをみていきます。
たとえば、Ubuntu 16.04 LTS 標準のままの apt もしくは apt-get でインストールすると、古いバージョンがインストールされます。
$ sudo apt install nodejs
このことをふまえながら Google 検索してみていくと、Ubuntu では、多くの方が n というバージョン管理パッケージを利用しているようです。
npm も含めてインストールは簡単に、という思いもあり、以下のページの手順でインストールを進めました。
https://nodejs.org/
LTS( long-term support )版の場合。
$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt install -y nodejs
最新版の場合。
$ curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
$ sudo apt install -y nodejs
この手順では、Node.js とともに npm もインストールされます。また、nodejs コマンドのほか、node コマンドでも使えるようになっています。
次に、npm を利用して、ws.js、express.js、https.js http.js をインストールします。
$ npm install ws express https http
さて、今回使用した SSL/TLS 証明書は、プライベート認証局(CA)を作成して、プライベート SSL/TLS 証明書を発行したものです。この手順については、プライベート認証局でプライベート SSL/TLS 証明書を発行する も参考にしてください。
今回作成した Secure WebSocket サーバーのコード例です。
var WebSocket = require('ws');
var fs = require('fs');
var http = require('http');
var https = require('https');
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/'));
var server = http.createServer(app);
var wss = new WebSocket.Server({server:server});
var _ca_certs = '/etc/ssl/certs/ca.crt';
var _certfile = '/etc/ssl/certs/client.crt';
var _keyfile = '/etc/ssl/certs/client.key';
var key = fs.readFileSync(_keyfile);
var cert = fs.readFileSync(_certfile);
var ca = fs.readFileSync(_ca_certs);
var options = {
key: key,
cert: cert,
ca: ca
};
var server_secure = https.createServer(options, app);
var wss_secure = new WebSocket.Server({server:server_secure});
// すべての接続へブロードキャスト
wss.broadcast = function broadcast(data) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
};
wss_secure.broadcast = function broadcast(data) {
wss_secure.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
};
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(data) {
// ほかの接続へブロードキャスト
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
wss_secure.broadcast(data);
});
wss_secure.on('connection', function connection(ws) {
ws.on('message', function incoming(data) {
// ほかの接続へブロードキャスト
wss_secure.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
wss.broadcast(data);
});
server.listen(8080);
server_secure.listen(8081);
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const server = new https.createServer({
cert: fs.readFileSync('/path/to/cert.pem'),
key: fs.readFileSync('/path/to/key.pem')
});
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
server.listen(8080);
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
// Broadcast to all.
wss.broadcast = function broadcast(data) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
};
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(data) {
// Broadcast to everyone else.
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
});
Sending and receiving text data のコード例です。
const WebSocket = require('ws');
const ws = new WebSocket('ws://www.host.com/path');
ws.on('open', function open() {
ws.send('something');
});
ws.on('message', function incoming(data) {
console.log(data);
});
ws:// のテスト用クライアントは、ホスト名とポート、パスをサーバー側にあわせます。
次に、wss:// のテスト用クライアントコード例です。
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const WebSocket = require('ws');
const ws = new WebSocket('wss://www.host.com:8081');
ws.on('open', function open() {
ws.send('something');
});
ws.on('message', function incoming(data) {
console.log(data);
});
なお、コードの先頭行は、プライベート認証局の CA 証明書を使用した場合の、次のエラーを回避するものです。プライベート認証局の CA 証明書は、Node.js 向けに信頼されたルート証明機関の証明書ではないことによります。
Error: self signed certificate in certificate chain
または、一時的にプライベート認証局の CA 証明書を設定する環境変数を、実行コマンドの前に加える方法があります。
$ NODE_EXTRA_CA_CERTS='/etc/ssl/ca.crt' node wssclient.js