【Nginx】Websocketの設定備忘録
2021/11/21
プロジェクトでsocketを扱っていると、nginxでwebsocketの設定をする機会が時々あります。
そのたびに調べて設定している気がするので、自分用の備忘録としてwebsocket用のnginx.conf
をまとめておきたいと思います。
nginx詳しい方は公式の説明見た方が早いかも...
nginx.conf
default
基本的にはnginx.conf
の転送設定部分だけを変更すれば、nginxを通してwebsocketを使えるようにできます。
まず一般的なhttpの転送設定部分を確認します。
http {
...
server {
listen 80;
listen [::]:80;
server_name _;
location / {
proxy_pass http://127.0.0.1:APIのport;
}
...
}
}
WebSocket
次にwebsocket用の転送設定です。 上記の転送設定部分を↓のように変更すればWebsocket用の設定としてはOKです。
http {
...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name _;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://127.0.0.1:WSのport;
}
...
}
}
補足説明
色々追加されているように見えますが、上記のwebsocket用の設定は、リクエストHeaderのConnection
、Upgrade
属性をproxy先へ渡すようにしてるだけです。
以下ではnginx.conf
の各部分についてもう少し詳細に説明しています。
map部分
nginxのmapは第一パラメータの値に応じて複数の変数に値を設定できる機能です。
下の例では$http_upgrade
の値が空の場合は、$connection_upgrade
にclose
を設定し、それ以外の場合は、$connection_upgrade
にupgrade
を設定しています。
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
ここで設定した$connection_upgrade
の変数は次のlocation部分で使用します。
尚、$http_upgrade
にはリクエストheaderのUpgrade
属性が入っています。
※ nginxは$http_属性名
にリクエストheaderの各属性がデフォルトで入る仕様です。
Upgrade
属性はすでに確立されたプロトコルを異なるプロトコル(今回の場合はwebsocket)にアップグレードするために用意されたheader属性です。
参考)https://developer.mozilla.org/ja/docs/Web/HTTP/Protocol_upgrade_mechanism
location部分
以下のlocation部分の設定は/...
へのリクエストをproxy先(proxy_pass
)へ特定のheaderをくっつけて渡す設定です。
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://127.0.0.1:WSのport;
}
はじめにwebsocket切り替えのためのプロトコルupgradeはHTTP/1.1
固有の機能なのでproxy_http_version
を1.1
としています。
また、nginxはプロトコルのupgrade機能に関連したheader属性(Upgrade
、Connection
)を、proxy先へデフォルトでは渡しません(通常の属性はそのまま渡してくれる場合がほとんど)。
そこで、proxy_set_header Upgrade $http_upgrade;
、proxy_set_header Connection $connection_upgrade;
と明示的に記載することで、proxy先のheaderにプロトコルupgrade用の各属性を渡すようにしています。
これによりproxy先のserverは例えば以下のようなHeaderを持つリクエストを受け取ることになります。
GET /resource HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: E4WSE...
Upgrade
、Connection
属性を受け取ったserverはプロトコルをwebsocketへ切り替えてclientとの通信を開始します。
終わり
これでwebsocket用の設定がすぐできるようになる...はず...