我使用nginx 1.4.6作为Django应用程序和使用socket.io 1.2.1以及socketio-jwt 2.3.5的相关NodeJS应用程序的代理
在本地,我使用Vagrant实例(ubuntu 14.04.1)编码,而远程我使用专用的AWS EC2实例 - 两者都使用相同的Vagrantfile和安装shell脚本进行配置,因此他们& #39;非常接近相同。
在本地运行时,我的客户端连接到nginx服务器,该服务器升级连接并将其传递给Node下的socket.io服务器实现。一切都很好。
远程地,我记录了与transport=polling
的第一个连接,该连接还指示客户端升级到websocket传输,然后是transport=websockets
的第二个请求,然后是transport=polling
的第三个请求。
虽然应用程序仍然有效,但轮询< websockets有很多原因,我希望我能找到一种方法来解决这个问题。
第二个请求以400 Bad Request
回答。使用DEBUG=* node index.js
运行我的节点应用程序会提供以下输出:
engine intercepting request for path "/socket.io/" +24s
engine handling "GET" http request "/socket.io/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hcmNlbCIsIm9yaWdfaWF0IjoxNDE4MDU5ODg1LCJ1c2VyX2lkIjozLCJlbWFpbCI6IiIsImV4cCI6MTQxODE0NjI4NX0.2PE0TNRol9G4hby4OzQ-af2e0yjfgFAb-gQJF5tKWRwxWnFLv1NGp3Yo87UaqNaQceMW6KqzMIx2gLcRFnk09A&EIO=3&transport=polling&t=1418062322853-0" +0ms
engine handshaking client "6YDFOjBfvZ9UyutVAAAB" +1ms
engine:socket sending packet "open" ({"sid":"6YDFOjBfvZ9UyutVAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}) +0ms
engine:polling setting request +0ms
engine:socket flushing buffer to transport +0ms
engine:polling writing " �0{"sid":"6YDFOjBfvZ9UyutVAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}" +1ms
engine:socket executing batch send callback +1ms
socket.io:server incoming connection with id 6YDFOjBfvZ9UyutVAAAB +1.7m
socket.io:client connecting to namespace / +1.7m
socket.io:namespace adding socket to nsp / +1.7m
socket.io:socket socket connected - writing packet +1.7m
socket.io:socket joining room 6YDFOjBfvZ9UyutVAAAB +0ms
socket.io:client writing packet {"type":0,"nsp":"/"} +79ms
socket.io-parser encoding packet {"type":0,"nsp":"/"} +1.7m
socket.io-parser encoded {"type":0,"nsp":"/"} as 0 +0ms
engine:socket sending packet "message" (0) +79ms
socket id: "6YDFOjBfvZ9UyutVAAAB" connected to user: "marcel"
socket.io:socket joined room 6YDFOjBfvZ9UyutVAAAB +1ms
engine intercepting request for path "/socket.io/" +121ms
engine handling "GET" http request "/socket.io/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hcmNlbCIsIm9yaWdfaWF0IjoxNDE4MDU5ODg1LCJ1c2VyX2lkIjozLCJlbWFpbCI6IiIsImV4cCI6MTQxODE0NjI4NX0.2PE0TNRol9G4hby4OzQ-af2e0yjfgFAb-gQJF5tKWRwxWnFLv1NGp3Yo87UaqNaQceMW6KqzMIx2gLcRFnk09A&EIO=3&transport=polling&t=1418062323048-1&sid=6YDFOjBfvZ9UyutVAAAB" +0ms
engine setting new request for existing client +1ms
engine:polling setting request +0ms
engine:socket flushing buffer to transport +1ms
engine:polling writing "�40" +38ms
engine:socket executing batch send callback +1ms
engine intercepting request for path "/socket.io/" +0ms
engine handling "GET" http request "/socket.io/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hcmNlbCIsIm9yaWdfaWF0IjoxNDE4MDU5ODg1LCJ1c2VyX2lkIjozLCJlbWFpbCI6IiIsImV4cCI6MTQxODE0NjI4NX0.2PE0TNRol9G4hby4OzQ-af2e0yjfgFAb-gQJF5tKWRwxWnFLv1NGp3Yo87UaqNaQceMW6KqzMIx2gLcRFnk09A&EIO=3&transport=websocket&sid=6YDFOjBfvZ9UyutVAAAB" +1ms
engine bad request: unexpected transport without upgrade +0ms
engine intercepting request for path "/socket.io/" +120ms
engine handling "GET" http request "/socket.io/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hcmNlbCIsIm9yaWdfaWF0IjoxNDE4MDU5ODg1LCJ1c2VyX2lkIjozLCJlbWFpbCI6IiIsImV4cCI6MTQxODE0NjI4NX0.2PE0TNRol9G4hby4OzQ-af2e0yjfgFAb-gQJF5tKWRwxWnFLv1NGp3Yo87UaqNaQceMW6KqzMIx2gLcRFnk09A&EIO=3&transport=polling&t=1418062323180-2&sid=6YDFOjBfvZ9UyutVAAAB" +1ms
engine setting new request for existing client +0ms
engine:polling setting request +0ms
问题似乎与第engine bad request: unexpected transport without upgrade +0ms
行有关,但我不明白。 nginx配置肯定提到升级,它适用于我的流浪机。
nginx配置的相关部分如下:
server {
...
location / {
...
}
location /socket.io/ {
proxy_pass http://127.0.0.1:4000/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
}
}
我能想到的本地和远程设置之间的唯一不同点是本地,客户端连接到两个不同端口上的localhost(我代理nginx后面的Node应用程序,但Web应用程序通过Gulp运行),远程节点应用程序位于不同的域上,位于端口80后面。
任何线索都非常感激:)
答案 0 :(得分:1)
我遇到了完全相同的问题。在查看一些tcp捕获后,看起来nginx甚至没有收到传入的Upgrade头,所以它没有将它传递给node.js. (我确实怀疑cloudflare这样做,但我不确定)。
我解决这个问题的方式非常糟糕,但确实很有效。基本上我修改了nginx配置以查找Sec-Websocket-Key
标头,当它找到时,它将Upgrade标头设置为websocket
,将Connection标头设置为upgrade
。这很有效。
示例配置:
map $http_sec_websocket_key $upgr {
"" ""; # If the Sec-Websocket-Key header is empty, send no upgrade header
default "websocket"; # If the header is present, set Upgrade to "websocket"
}
map $http_sec_websocket_key $conn {
"" $http_connection; # If no Sec-Websocket-Key header exists, set $conn to the incoming Connection header
default "upgrade"; # Otherwise, set $conn to upgrade
}
您必须在server {}
阻止之前定义这两个地图块。
现在在你的socket.io位置添加以下两行:
proxy_set_header Upgrade $upgr;
proxy_set_header Connection $conn;
这会将Upgrade和Connection标头设置为映射值。
我希望这也是你问题的解决方案。