Table of Contents [expand]
最終更新日 2025年09月05日(金)
このチュートリアルでは、Heroku 上のリアルタイム Node.js アプリケーションの概要を説明します。サーバーの現在時刻を永続的なソケット接続経由でクライアントと共有する単純なアプリケーションを開発します。各アプリケーションは、Node の一般的な express Web サーバーに基づきます。
リアルタイム Node.js アプリケーションを開発する場合は、直接 WebSocket を使用できます。WebSocket プロトコルをサポートしていないクライアントにフォールバックを提供する Socket.io などの抽象化ライブラリを使用することもできます。両方のオプションを示します。
dyno を使用してこのチュートリアルを完了した場合、使用量のカウントに入ります。低料金プランを使用してこのチュートリアルを完了することをお勧めします。資格のある学生の皆様は、新しい Heroku for GitHub Students プログラムを通じてプラットフォームクレジットを申請できます。
WebSocket 対応アプリの設定
アプリのディレクトリに移動し、デフォルトの package.json を作成します。
$ npm init --yes
package.json で Node のバージョンを指定し、アプリを起動するためのメカニズムを指定します。
"engines": {
"node": "22.x"
},
"scripts": {
"start": "node server.js"
}
依存関係のインストール
基本的な express Web サーバーから始めましょう。
$ npm install --save express
WebSocket 接続を使用するための最も簡単な方法は、ws モジュールを使用することです。そのために、ws、bufferutil、utf-8-validate の各モジュールをインストールします。必要なのは ws モジュールだけですが、bufferutil および utf-8-validate モジュールによりパフォーマンスが向上します。
$ npm install --save ws bufferutil utf-8-validate
サーバーの作成
以下の内容を含む、server.js という名前のファイルをアプリディレクトリのルートに作成します。
const express = require('express')
const { Server } = require('ws')
const PORT = process.env.PORT || 5001
const INDEX = '/index.html'
const server = express()
.use((req, res) => res.sendFile(INDEX, { root: __dirname }))
.listen(PORT, () => console.log(`Listening on ${PORT}`))
const wss = new Server({ server })
wss.on('connection', (ws) => {
console.log('Client connected')
ws.on('close', () => console.log('Client disconnected'))
});
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString())
})
}, 1000)
WebSocket 接続の受け入れ
WebSocket 接続を受け入れるには、HTTP サーバーで次の 2 つの処理を実行する必要があります。 - クライアント側のアセットを提供します。 - WebSocket サーバーがリクエストを監視するためのフックを提供します。
これは、server.js 内で次のコード行によって処理されます。
const PORT = process.env.PORT || 5001
const INDEX = '/index.html'
const server = express()
.use((req, res) => res.sendFile(INDEX, { root: __dirname }))
.listen(PORT, () => console.log(`Listening on ${PORT}`))
次に WebSocket サーバーは、イベントをリッスンできるように、HTTP サーバーを引数として受け取る必要があります。これは、server.js 内で次のコード行によって処理されます。
const { Server } = require('ws')
const wss = new Server({ server })
最後に、接続と切断をリッスンしてログに記録します。クライアントが接続されたら、そのクライアントからのメッセージのためのイベントハンドラを追加できます。server.js 内で、これは次のコード行によって処理されます。
wss.on('connection', (ws) => {
console.log('Client connected')
ws.on('close', () => console.log('Client disconnected'))
})
最新情報のブロードキャスト
ソケット接続の利点の 1 つは、サーバーがクライアントリクエストを待機することなく、データをクライアントにブロードキャストできることです。このサンプルアプリでは、server.js からの次のコードを使用して、1 秒ごとに現在時刻をすべてのクライアントにプッシュします。
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString())
});
}, 1000)
WebSocket クライアントの作成
以下の内容を含む、index.js という名前のファイルをアプリディレクトリのルートに作成します。
<html>
<head>
<script>
let HOST = location.origin.replace(/^http/, 'ws')
let ws = new WebSocket(HOST);
let el;
ws.onmessage = (event) => {
el = document.getElementById('server-time');
el.innerHTML = 'Server time: ' + event.data;
};
</script>
</head>
<body>
<p id="server-time"></p>
</body>
</html>
これは、サーバーからの時刻の更新をリッスンする単純な HTML ページです。WebSocket サーバーに接続し、ブロードキャストされたメッセージをリッスンして、これらのメッセージをページに書き込みます。
アプリの起動
これでサーバーを起動できるようになりました。
$ npm start
> node server.js
Listening on 5001
http://localhost:5001 でアプリをローカルにテストして、時刻がリアルタイムに更新されることを確認します。サーバーログにも Client connected と記録されます。
動作に満足したら、.gitignore に追加する node_modules を除いたすべてのファイルを Git にコミットします。次に、アプリを Heroku にデプロイします。
$ heroku create
git commit -am 'websocket starting point'
git push heroku main
heroku open
理解を深める
Socket.io のようなライブラリを使用すると、リアルタイムアプリケーションをより堅牢にすることができます。HTTP ロングポーリングなどのメソッドにフォールバックして、WebSocket に対応していないユーザーにサービスを提供したり、自動再接続を処理したり、多重化や名前空間ルームなどの高度な機能を提供したりできます。
リアルタイムアプリをクラスタモードで実行する場合、または複数の dyno にスケーリングする場合は、セッションアフィニティを有効にすることをお勧めします。
$ heroku features:enable http-session-affinity