Expressとsocket.ioを使用してnode.jsで記述された基本的なチャットアプリがあります。ポート3000でノードに直接接続する場合は正常に機能します
しかし、nginxv1.4.2をプロキシとして使用しようとすると機能しません。
接続マップを使用して開始します
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
次に、場所を追加します
location /socket.io/ {
proxy_pass http://node;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_Host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-Id $txid;
proxy_set_header X-Session-Id $uid_set+$uid_got;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 86400;
keepalive_timeout 90;
proxy_cache off;
access_log /var/log/nginx/webservice.access.log;
error_log /var/log/nginx/webservice.error.log;
}
location /web-service/ {
proxy_pass http://node;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_Host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-Id $txid;
proxy_set_header X-Session-Id $uid_set+$uid_got;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 86400;
keepalive_timeout 90;
access_log /var/log/nginx/webservice.access.log;
error_log /var/log/nginx/webservice.error.log;
rewrite /web-service/(.*) /$1 break;
proxy_cache off;
}
これらは、私が見つけたすべてのヒントを使用して構築されています。エラーログにはエラーは表示されません。 (エラーロギングが機能していることをテストするためにノードを停止した場合を除く)
Nginxを使用すると、開発ツールに101のステータスのWebSocket接続が表示されます。しかし、結果の下のフレームタブは空です。応答ヘッダーに表示される唯一の違いは、nginxを介した大文字と小文字の違い(「アップグレード」と「アップグレード」)です。
Connection:upgrade
Date:Fri, 08 Nov 2013 11:49:25 GMT
Sec-WebSocket-Accept:LGB+iEBb8Ql9zYfqNfuuXzdzjgg=
Server:nginx/1.4.2
Upgrade:websocket
ノードから直接
Connection:Upgrade
Sec-WebSocket-Accept:8nwPpvg+4wKMOyQBEvxWXutd8YY=
Upgrade:websocket
ノードからの出力(nginxを介して使用する場合)
debug - served static content /socket.io.js
debug - client authorized
info - handshake authorized iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/websocket/iaej2VQlsbLFIhachyb1
debug - set heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"name":"message","args":[{"message":"welcome to the chat"}]}
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client 7My3F4CuvZC0I4Olhybz
debug - jsonppolling closed due to exceeded duration
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client AkCYl0nWNZAHeyUihyb0
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/xhr-polling/iaej2VQlsbLFIhachyb1?t=1383911206158
debug - setting poll timeout
debug - discarding transport
debug - cleared heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911216160&i=0
debug - setting poll timeout
debug - discarding transport
debug - clearing poll timeout
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client iaej2VQlsbLFIhachyb1
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911236429&i=0
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client iaej2VQlsbLFIhachyb1
ノードに直接接続する場合、クライアントはポーリングを開始しません。
通常のhttpスタッフノードの出力はnginxで正常に機能します。
明らかに私が見ていない何かですが、私は立ち往生しています、ありがとう:)
次のような最小限の構成を試しましたか?
location /socket.io/ {
proxy_pass http://node;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $Host;
}
場合によっては値が異なる可能性があるため、$ http_Hostから$ Hostへの変更にも注意してください。 https://stackoverflow.com/questions/15414810/whats-the-difference-of-Host-and-http- Host-in-nginx
Web Socketをプロキシするためにnginxを導入したときに、同じ問題が発生しました。問題は、nodejsで接続をすぐにWebSocketにすることを強制したことでした。この力を取り除くと、最初にポーリングでネゴシエートし、次に自動的にアップグレードします。
クライアント側では、トランスポートについてコメントしました。
//transports:['websocket', 'polling'] this was not permiting my connection with nginx
io(this.adress, {query: 'auth_cookie='+this.auth_cookie});
また、サーバー側のトランスポート構成を削除します。
完全を期すために、これは私のnginx構成です:
server {
listen 80;
server_name demo2.example.com;
location /socket.io {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $Host;
proxy_pass http://demo2.example.com:3012/socket.io;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
proxy_pass http://demo2.example.com:81;
}
}
お役に立てれば