🐈

NginxでWebSocket通信を設定する方法

2024/07/12に公開

WebSocketとは

一般的にREST APIはHTTPなどのプロトコルを使用したプル型のインターフェースです。クライアントからサーバーにリクエストを送信し、サーバーがレスポンスを返します。しかし、リアルタイム性を必要とするアプリケーションやサーバーからクライアントへのプッシュ通知などを実現するためには、WebSocketが有効です。WebSocketは、持続的な双方向通信を可能にするプロトコルです。

Nginxの設定

この設定は、WebSocket接続を扱うためのNginxの設定です。具体的には、クライアントからの接続がWebSocketプロトコルを使用しているかどうかを判断し、それに応じて接続を処理する方法です。

location /ws {
  proxy_pass http://xxxx:4000/ws; //通信先のアプリケーション
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade; 
  proxy_set_header Connection $connection_upgrade;
}
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

クライアントからUpgradeヘッダーを用いてWebサーバー(Nginx)へのリクエストが行われる際に、通信自体はHTTP/HTTPS通信で行われますが、Upgradeヘッダーの変数$http_upgradeがmapディレクティブによって、UpgradeヘッダーがWebSocketであるという条件分岐をNginxが行います。

default upgrade;は、$http_upgrade が空でない(つまり、何らかのUpgrade要求が存在する)場合に$connection_upgradeupgradeに設定します。これにより、WebSocketなどのプロトコルへのアップグレードが可能になるという仕組みです。

WebSocket接続をプロキシする場合

クライアントからのWebSocket通信のプロトコルは wss://(httpの場合は ws://)となりますが、Nginxの設定でproxy_passとして使用するプロトコルは http:または https:です。

NginxはクライアントからのWebSocketリクエストを受け取り、設定に基づいてそのリクエストをバックエンドのWebSocketサーバーに転送します。このとき、proxy_passディレクティブで指定されたプロトコル(http:またはhttps:)を使用してバックエンドサーバーと通信します。

デフォルトでは、NginxはHTTP/1.0を使用してプロキシリクエストを行います。しかし、HTTP/1.0は Upgrade ヘッダーをサポートしていないため、WebSocket接続のプロキシには適していません。そのため、proxy_http_version 1.1;を設定することで、NginxがHTTP/1.1を使用してバックエンドサーバーと通信し、WebSocket接続のアップグレード要求を正しく処理できるようになります。

まとめ

proxy_set_headerを使用して、必要なヘッダー情報を設定し、WebSocketのプロトコルに対応できるように、mapディレクティブを使って、クライアントからのUpgradeヘッダーを処理し、WebSocket接続を適切にアップグレードする仕組みについての記事でした。

Discussion