Node.jsのWebSocket:サーバー、クライアント、ハートビート、再接続

Node.jsのWebSocket:wsサーバー、組み込みクライアント、ハートビート | We.Inc

wsパッケージでNode.jsのWebSocketサーバーを構築し、Node組み込みのWebSocketクライアントで接続し、pingとpongで死んだソケットを検出し、バックオフで再接続する方法を解説します。

Node.jsには組み込みのWebSocketサーバーがないため、多くのプロジェクトはwsパッケージをインストールしてWebSocketServerを作成します。クライアント側については、Nodeにブラウザー互換のグローバルWebSocketが用意されています。v21.0.0とv20.10.0で追加され、v22.0.0でフラグ不要になり、v22.4.0で安定版になりました。本番公開の前に、pingとpongのハートビートと、バックオフ付きの再接続を追加しましょう。

それぞれの役割

このガイドでは、小さなチャット風サーバーとそれに接続するクライアントを順番に作ります。エコーとブロードキャストを行うサーバー、依存関係なしで接続するNodeスクリプト、気づかないうちに切れた接続を破棄するハートビート、サーバー再起動後に復帰するクライアントです。下の計算ツールでは、コードに書く前にリトライの待ち時間がどう伸びるかを確認できます。

よくある質問

Node.jsにWebSocketは組み込まれていますか?

クライアントだけです。グローバルのWebSocketクラスはv21.0.0とv20.10.0で--experimental-websocketフラグ付きで登場し、v22.0.0でフラグが不要になり、v22.4.0で実験的機能ではなくなりました。組み込みのサーバーは今もないため、wsが定番の選択肢であり続けています。

wsとSocket.IOのどちらを使うべきですか?

wsは標準のWebSocketプロトコルを使うため、ブラウザーやNodeのグローバルを含むあらゆる標準クライアントが接続できます。Socket.IOはその上に独自プロトコルを載せ、ルームや自動再接続を提供しますが、相手側にも専用のクライアントライブラリが必要です。

closeイベントなしに接続が切れるのはなぜですか?

ノートPCのふたを閉じたときのようにネットワーク経路が消えると、closeフレームは送られず、サーバーには半開きのソケットが残ります。ハートビートはこれを見つけます。前回のpingに応答しなかったソケットは、次の周回で強制終了されます。

ブラウザーのクライアントからpingを送れますか?

いいえ。ブラウザーのAPIにはsend()とclose()しかありません。ただしブラウザーはサーバーからのpingに自動でpongを返すため、サーバー側のハートビートはブラウザーのクライアントでも機能します。

HTTPサーバーとポートを共有するには?

Expressやnode:httpなどでHTTPサーバーを自分で作成し、new WebSocketServer({ server })として渡します。アップグレードのリクエストはwsに、通常のリクエストはアプリに届きます。

接続はどう始まるか

ハートビートをわかりやすく

サーバーを叩きすぎずに再接続する

ステップ1:wsでサーバーを作る

server.js:エコーとブロードキャスト

各メッセージは開いているすべてのクライアントに送り返されます。errorリスナーにより、1つの不良ソケットでプロセスがクラッシュするのを防ぎます。

ステップ2:依存関係なしのクライアント

client.js:NodeのグローバルWebSocket

Node 22以降とブラウザーのコンソールの両方が同じWebSocketクラスを持つため、どちらでもそのまま動きます。

ステップ3:pingとpongで死んだ接続を切る

wsのREADMEにあるパターンを当社なりに書いたものです。pongで生存をマークし、前回の周回に応答しなかったものはすべて強制終了します。

ステップ4:再接続するクライアント

reconnect.js:ジッター付き指数バックオフ

待ち時間は失敗するたびに上限まで倍になり、ランダムなばらつきが加わり、接続が開くとリセットされます。

nginxの背後で使う

nginxは、UpgradeとConnectionのヘッダーを自分で転送したときだけアップグレードを通します。nginx 1.29.7より前では、proxy_http_version 1.1も必要です。

ソケット用のnginx location

proxy_read_timeoutで60秒のアイドル上限を延ばします。いずれにしても、上のハートビートが通信を流し続けます。

再接続の待ち時間計算ツール

最初の待ち時間、倍率、上限を設定すると、クライアントが各リトライ前に待つ時間と、ジッターを加えたときの最短と最長の待ち時間がわかります。

最初の待ち時間(ms)

倍率

上限(ms)

表示する試行回数

ジッターを加える(待ち時間の半分から全体の間で待つ)

各再接続試行前の待ち時間

試行

待ち時間

ジッターあり

累計待ち時間

{n}〜{v} 秒

同じ設定をコードで

無料で始める · クレジットカード不要

関連: ガイド|Webマーケティングと集客を学ぶ

製品

ご利用いただける方

機能

リソース

会社情報

サイトマップを見る