簡體   English   中英

Socket.io在遠程但不是本地時退回到nginx代理后面的輪詢(websocket給出400)

[英]Socket.io falling back to polling (websocket gives 400) behind nginx proxy when remote but not local

我使用nginx 1.4.6作為Django應用程序和使用socket.io 1.2.1以及socketio-jwt 2.3.5的相關NodeJS應用程序的代理

在本地,我使用Vagrant實例(ubuntu 14.04.1)進行編碼,而遠程我正在使用專用的AWS EC2實例 - 兩者都使用相同的Vagrantfile和setup shell腳本進行配置,因此它們非常接近相同。

在本地運行時,我的客戶端連接到nginx服務器,該服務器升級連接並將其傳遞給Node下的socket.io服務器實現。 一切都很好。

遠程地,我使用transport=polling記錄第一個連接,該連接還指示客戶端升級到websocket傳輸,然后是使用transport=websockets第二個請求,然后是另一個帶有transport=polling的第三個連接。

雖然應用程序仍然有效,但出於多種原因輪詢<websockets,我希望我能找到一種方法來對此進行排序。

第二個請求以400 Bad Request回答。 使用DEBUG=* node index.js運行我的Node應用程序將提供以下輸出:

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后面的不同域中。

任何線索非常感謝:)

我有完全相同的問題。 看一些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標頭設置為映射值。

我希望這也是你問題的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM