使用nginx的Socket.io

使用nginx的Socket.io,nginx,socket.io,Nginx,Socket.io,我试图通过nginx1.6为静态文件提供服务,并使用socket.io代理来自Node.js web服务器的socket流量 这是nginx.conf的相关部分: location /socket.io/ { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade;

我试图通过nginx1.6为静态文件提供服务,并使用socket.io代理来自Node.js web服务器的socket流量

这是nginx.conf的相关部分:

location /socket.io/ {
            proxy_pass http://localhost:3000;       
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
        }
它可以直接在浏览器和Node.js之间完美地工作,但是当使用nginx 1.6代理时,socket.io会花费太长时间。握手协议花费的时间太长,但如果不中断,它最终会在几分钟后开始工作

nginx提供的静态文件非常有效

有什么问题吗

更新:

我分析了一点网络流量,确定以下请求持续大约一分钟(正是请求升级的时间):

预期响应为代码101,并且:

Connection: upgrade
Sec-WebSocket-Accept: HXx3KKJadQYjDa11lpK5y1nENMM=
Upgrade: websocket
...
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8888
Connection: keep-alive
Content-Type: application/json
Server: nginx/1.6.2
Transfer-Encoding: chunked
相反,浏览器接收400和:

Connection: upgrade
Sec-WebSocket-Accept: HXx3KKJadQYjDa11lpK5y1nENMM=
Upgrade: websocket
...
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8888
Connection: keep-alive
Content-Type: application/json
Server: nginx/1.6.2
Transfer-Encoding: chunked
更新2:

我确定同样的配置在我的办公室电脑上也能完美工作,这意味着这是我的家庭电脑问题。无论如何,如果能确定到底出了什么问题,那就太好了。

我所看到的每个例子(,)都使用了:


注意所有小写的“升级”。您的示例的大写字母为“U”。也许值得一试。

你可能忘记了proxy\u重定向关闭

location / {
            proxy_pass http://localhost:3000/;
            include proxy_params;
            proxy_redirect off;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
    }
编辑:

我的消息来源:

RFC声明“升级”

来自服务器的握手如下所示:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    Sec-WebSocket-Protocol: chat
...
还说,

   ....
   3.  If the response lacks a |Connection| header field or the
   |Connection| header field doesn't contain a token that is an
   ASCII case-insensitive match for the value "Upgrade", the client
   MUST _Fail the WebSocket Connection_.
   ....
因此,是的,每个头都应该不区分大小写,但有些服务器,如Microsoft IIS/或特定于开发人员的实现,则不区分大小写


这完全取决于nginx之后的基础服务器,如果它接受不区分大小写的,则取决于它。

在正在运行的服务器中,此处使用的nginx配置是:

  # Requests for socket.io are passed on to Node on port 3000
  location ~* \.io {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy false;

      proxy_pass http://localhost:3000;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

看看!这里最重要的部分是这两个标志^已经失去了3天,直到我设法让nginx与socketio一起工作

location ^~ /socket {
            proxy_pass http://localhost:3001;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
}

我想你仍然有问题,就像我一样,这里是你需要做的:对齐3个配置。假设您希望通过“mysocket”进行通信:

尼金克斯:

  location /mysocket/ {
      proxy_pass http://localhost:3000; 
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }
nodejs:

const io = require('socket.io')(server, {
  path: '/mysocket'
});
客户:

var io = require('socket.io-client');
const socket = io('http://myserver.com, {
    path: '/mysocket'
});

家庭和办公系统的系统配置有很大的不同吗?感谢“海瑟斯”、亚伯拉罕神父、佛陀和地球母亲!海滨。数码谢谢你。很有魅力。三年多过去了,仍然很有魅力!谢谢。真不敢相信我花了几个月的时间想弄明白这一点。工作起来很有魅力!这是一个救世主。谢谢。我没有意识到路径也需要传递到服务器,你在那里解决了我的问题。但是您的
服务器
变量代表什么?没有它,我的也可以正常工作。@JamesBatchelor模块“http”的简单http服务器。变量服务器是可选的您的客户端和服务器文件是什么样子的?还有什么版本的socket.io,我已经是第三天了!
var io = require('socket.io-client');
const socket = io('http://myserver.com, {
    path: '/mysocket'
});