thumbnail

【Nginx】Websocketの設定備忘録

2021/11/21

プロジェクトでsocketを扱っていると、nginxでwebsocketの設定をする機会が時々あります。 そのたびに調べて設定している気がするので、自分用の備忘録としてwebsocket用のnginx.confをまとめておきたいと思います。

nginx詳しい方は公式の説明見た方が早いかも...

nginx.conf

default

基本的にはnginx.confの転送設定部分だけを変更すれば、nginxを通してwebsocketを使えるようにできます。 まず一般的なhttpの転送設定部分を確認します。

nginx.conf
http {
    ...

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;

        location / {
            proxy_pass   http://127.0.0.1:APIのport;
        }

        ...
    }
}

WebSocket

次にwebsocket用の転送設定です。 上記の転送設定部分を↓のように変更すればWebsocket用の設定としてはOKです。

nginx.conf
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のConnectionUpgrade属性をproxy先へ渡すようにしてるだけです。

以下ではnginx.confの各部分についてもう少し詳細に説明しています。

map部分

nginxのmapは第一パラメータの値に応じて複数の変数に値を設定できる機能です。 下の例では$http_upgradeの値が空の場合は、$connection_upgradecloseを設定し、それ以外の場合は、$connection_upgradeupgradeを設定しています。

nginx.conf
    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をくっつけて渡す設定です。

nginx.conf
	      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_version1.1としています。

また、nginxはプロトコルのupgrade機能に関連したheader属性(UpgradeConnection)を、proxy先へデフォルトでは渡しません(通常の属性はそのまま渡してくれる場合がほとんど)。

そこで、proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;と明示的に記載することで、proxy先のheaderにプロトコルupgrade用の各属性を渡すようにしています。

これによりproxy先のserverは例えば以下のようなHeaderを持つリクエストを受け取ることになります。

Header
GET /resource HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: E4WSE...

UpgradeConnection属性を受け取ったserverはプロトコルをwebsocketへ切り替えてclientとの通信を開始します。

終わり

これでwebsocket用の設定がすぐできるようになる...はず...

author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

Profile

author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

© 2022 mitsuru takahashi