この記事では、Node.js と Socket.IO で NGINX と NGINX Plus を使用する方法について説明します。 WebSocket と NGINX を使用してリアルタイム Web アプリケーションを構築する方法に関する投稿は非常に好評でしたので、この投稿では、Socket.IO を使用したドキュメントとベスト プラクティスについて引き続き説明します。
Socket.IO は、Node.js アプリケーションの普及に伴い非常に人気が高まった WebSocket API です。 この API は、オンライン ゲームやチャットなどのリアルタイム アプリの構築を簡単にするため、よく知られています。 NGINX 1.3.13 以降およびすべての NGINX Plus リリースでは、WebSocket 接続のプロキシがサポートされており、Socket.IO を利用できます。 WebSocket プロトコルは、単一の TCP 接続を介して全二重、つまり双方向の通信を可能にします。
運用環境で実行されるアプリケーションは、通常、ポート 80 (HTTP)、ポート 443 (HTTPS)、またはその両方で実行する必要があります。 アプリケーションの複数のコンポーネントがユーザーと対話する場合、またはポート 80 で Web サーバーを使用して他のアセットを配信する場合、これは困難になる可能性があります。 このため、Socket.IO サーバーにプロキシする必要があり、NGINX がそれを実行する最適な方法です。 バックエンド アプリケーションのインスタンスが 1 つでも、数百でも、NGINX は複数のノードを使用するときにアップストリームの負荷を分散することもできます。
Node.js をインストールするには、適切なディストリビューションをダウンロードします(またはパッケージ マネージャーを使用してインストールします)。 npm
install
socket.io
コマンドを実行して Socket.IO をインストールします。
この例では、リアルタイム アプリの Socket.IO サーバーがポート 5000 で実行されていると想定しています。 以下はserver.jsノード アプリケーション ファイルのテンプレートです。これはサーバーとして機能し、受信リクエストを Socket.IO サーバーを実行している適切なポートにルーティングする基本プログラムです。
var io = require('socket.io').listen(5000);
io.sockets.on('connection', function (socket) {
socket.on('set nickname', function (name) {
socket.set('nickname', name, function () {
socket.emit('ready');
});
});
socket.on('msg', function () {
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
});
});
});
クライアントに配信されるファイル (例: index.html ) に次のような JavaScript コードを追加します。 この例では、ユーザーのブラウザで WebSocket を作成するために、アプリケーションへの接続を要求します。
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io(); // ここに初期化コードを記述します。
</script>
アプリケーションに複数のインスタンスがある場合、NGINX と NGINX Plus は負荷分散を行い、ユーザー セッションを複数のノードに分散できます。 NGINX または NGINX Plus 構成のhttp
コンテキストに、upstream グループ内のノードを定義するためのuploaded
ブロックを含めます。
次の例に示すように、サーバー
ディレクティブにweight
パラメータを含めることで、サーバーに送信されるトラフィックの割合を設定できます。 ここで、 srv1.app.com は他のサーバーよりも 5 倍多くのセッションを受信します。 NGINX Plus は、強化された負荷分散方法と、セッション永続性、ヘルスチェック、拡張ステータス レポート、負荷分散されたサーバー グループのオンザフライ再構成を追加することで、NGINX のリバース プロキシ機能を拡張します。
# http{} 構成ブロック内
upstream socket_nodes {
ip_hash;
server srv1.app.com:5000 weight=5;
server srv2.app.com:5000;
server srv3.app.com:5000;
server srv4.app.com:5000;
}
アップストリーム サーバーのグループが宣言されたので、トラフィックをそのグループに送信するように仮想サーバーを構成する必要があります。 少なくとも、 proxy_pass
ディレクティブを含め、アップストリーム グループに名前を付けます。 WebSocket プロトコルは HTTP/1.1 で導入されたUpgrade
ヘッダーを使用するため、 proxy_http_version
ディレクティブを含めます。
server {
server_name app.domain.com;
location / {
proxy_set_header アップグレード $http_upgrade;
proxy_set_header 接続 "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header ホスト $host;
proxy_pass http://socket_nodes;
}
}
静的アセットを配信するには、NGINX プロキシ リクエストをアップストリーム Node.js インスタンスに送信できますが、ほとんどの場合、NGINX で直接リクエストを処理する方が効率的です。
上記のserver
ブロックのserver_name
ディレクティブと組み合わせて、次のlocation
ブロックは、NGINX に対して、 http://app.domain.com/assets/内のコンテンツに対するクライアントの要求に応答し、ローカルの/path/to/assetsディレクトリからコンテンツを提供するように指示します。 静的ファイルの処理をさらに最適化したり、ニーズに合わせてキャッシュの有効期限設定を設定したりできます。
場所 /assets {
エイリアス /path/to/assets;
access_log off;
有効期限 max;
}
次のエラーが表示された場合は、NGINX 1.3 より前のバージョンを実行している可能性があります。 WebSocket の使用は、NGINX 1.3.13 以降でサポートされています。
'...' への WebSocket 接続に失敗しました: WebSocket ハンドシェイク中にエラーが発生しました: 「接続」ヘッダーの値が「アップグレード」ではありません: キープアライブ socket.io.js:2371
NGINX Plus をお試しいただくには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、使用事例についてご相談ください。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"