【问题标题】:Socket.io with nginx带有 nginx 的 Socket.io
【发布时间】:2015-05-16 14:56:31
【问题描述】:

我正在尝试通过 nginx 1.6 提供静态文件,并使用 socket.io 代理来自 Node.js Web 服务器的套接字流量。

这是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 之间完美运行,但是 socket.io 在使用 nginx 1.6 代理时花费的时间太长。握手协议需要花费太多时间,但如果不中断,它最终会在几分钟后开始工作。

通过 nginx 传递静态文件完美运行。

可能是什么问题?

更新:

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

Sec-WebSocket-Key: LhZ1frRdl+myuwyR/T03lQ==
Cookie: io=1-A7tpvwmoGbrSvTAAA5
Connection: keep-alive, Upgrade
Upgrade: websocket
....

预期的响应是代码 101 并且:

Connection: upgrade
Sec-WebSocket-Accept: HXx3KKJadQYjDa11lpK5y1nENMM=
Upgrade: websocket
...

相反,浏览器收到 400 并且:

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:

我确定相同的配置在我的办公室计算机上完美运行,这意味着这是我家用计算机的问题。无论如何,确定到底出了什么问题会非常好。

【问题讨论】:

  • 家庭和办公系统的系统配置差别大吗?

标签: nginx socket.io


【解决方案1】:

在一个正在运行的服务器中,这里使用的 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";
    }

【讨论】:

  • 感谢“hay Seuss”、亚伯拉罕神父、佛陀和地球母亲! Beachfront.Digital 谢谢你。
  • 像魅力一样工作。
  • 3 年多过去了,仍然像魅力一样工作!谢谢
  • 非常感谢。我不敢相信我花了几个月的时间试图弄清楚这一点。像魅力一样工作!
  • 这是救生员。谢谢。
【解决方案2】:

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

niginx:

  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'
});

【讨论】:

  • 我没有意识到需要传递给服务器的路径,你在那里解决了我的问题。但是您的 server 变量代表什么?没有它我的工作正常。
  • @JamesBatchelor 模块“http”的简单 http 服务器。变量服务器是可选的
【解决方案3】:

我见过的每个示例(Nginx docsNginx blog)都使用:

proxy_set_header Connection "upgrade";

注意所有小写的“升级”。你的例子有一个大写的“U”。也许值得一试。

【讨论】:

    【解决方案4】:

    看看吧!这里最重要的部分是这 2 个迹象 ^~ 已经失去了 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;
    }
    

    【讨论】:

    • 您的客户端和服务器文件是什么样的?还有什么版本的socket.io,我已经第三天了!
    【解决方案5】:

    如何修复WebSocket在连接建立之前关闭。

    在本地回答我的套接字 io 连接工作正常,但在生产中,它不工作,出现错误 WebSocket 错误

    我通过在我的 Nginx conf 中添加此配置部分来解决此问题

                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;
    }```
    

    【讨论】:

      【解决方案6】:

      您可能忘记关闭 proxy_redirect;

      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";
          }
      

      编辑:

      我的来源:https://www.nginx.com/blog/websocket-nginx/

      RFC 声明“升级”https://www.rfc-editor.org/rfc/rfc6455#section-1.2

       ...
         The handshake from the client looks as follows:
      
          GET /chat HTTP/1.1
          Host: server.example.com
          Upgrade: websocket
          Connection: Upgrade
          Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
          Origin: http://example.com
          Sec-WebSocket-Protocol: chat, superchat
          Sec-WebSocket-Version: 13
      

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

          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之后的底层服务器,它是否接受不区分大小写。

      【讨论】:

        猜你喜欢
        • 2017-07-27
        • 2017-10-30
        • 1970-01-01
        • 2014-12-18
        • 2017-06-13
        • 1970-01-01
        • 1970-01-01
        • 2013-11-24
        • 2018-08-27
        相关资源
        最近更新 更多