エラー内容
タイトルの構成でアプリケーションを作っていた時に以下のエラーが出てつまずいた
socket io failed: Error during WebSocket handshake: Unexpected response code: 400
何故起きたか
WebSocket接続のハンドシェイク時に HTTP/1.1 101 (Switching Procotols)
というステータスコードと Hop-by-Hopヘッダ
を使用してWebSocket通信への切り替えを行う仕様に Nginx v1.3.13
から変更されたらしい。
Since version 1.3.13, nginx implements special mode of operation that allows setting up a tunnel between a client and proxied server if the proxied server returned a response with the code 101 (Switching Protocols), and the client asked for a protocol switch via the "Upgrade" header in a request.
解決策
Upgrade ヘッダ
と Connection ヘッダ
を明示的にバックエンドに渡すようにする必要がある
以下がNGINXのdefault.confです
/
にきたアクセスは nodeコンテナ
の3000番ポートに飛ばしています
/socket.io/
も明示的に設定することでフロントで呼び出す際に /socket.io/socket.io.js
で呼び出す事が出来ます
server {
listen 80;
server_name localhost;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Host $host;
proxy_pass http://node:3000;
}
location /socket.io/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_set_header Host $host;
proxy_pass http://node:3000;
}
}
docker-compose環境で構築している場合は NGINXの設定をした際に必ずbuildし直すことを忘れずに