使用 nginx 的 Meteor WebSocket 握手错误 400

Posted

技术标签:

【中文标题】使用 nginx 的 Meteor WebSocket 握手错误 400【英文标题】:Meteor WebSocket handshake error 400 with nginx 【发布时间】:2013-06-05 13:59:10 【问题描述】:

我设法在我的基础设施(Webfactions)上部署了流星。 该应用程序似乎工作正常,但是当我的应用程序启动时,我在浏览器控制台中收到以下错误:

WebSocket connection to 'ws://.../websocket' failed: Error during WebSocket handshake: Unexpected response code: 400

【问题讨论】:

@DanDascalescu 我应该编辑问题吗? 【参考方案1】:

WebSocket 速度很快,您不必(也不应该)禁用它们。

这个错误的真正原因是Webfactions使用了nginx,而nginx配置不当。这是correctly configure nginx to proxy WebSocket requests的方法,通过设置proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;

# we're in the http context here
map $http_upgrade $connection_upgrade 
  default upgrade;
  ''      close;


# the Meteor / Node.js app server
server 
  server_name yourdomain.com;

  access_log /etc/nginx/logs/yourapp.access;
  error_log /etc/nginx/logs/yourapp.error error;

  location / 
    proxy_pass http://localhost:3000;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;  # pass the host header - http://wiki.nginx.org/HttpProxyModule#proxy_pass

    proxy_http_version 1.1;  # recommended with keepalive connections - http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version

    # WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
  


这是基于David Weldon's nginx config改进的nginx配置。 Andrew Mao 联系了very similar configuration。

记住还要将HTTP_FORWARDED_COUNT 环境变量设置为应用程序前面的代理数量(通常为1)。

【讨论】:

谢谢丹。启用 websocket 是要走的路。还要升级 nginx 到 1.4 或更高版本来获取 websocket。 如果 Apache 也有这个就好了。 @KasperSouren:在绝大多数情况下,Apache 都是矫枉过正。我认为没有理由使用它。更多wikivs.com/wiki/Apache_vs_nginx Apache 绝对是矫枉过正,但我​​在我的大多数服务器上都运行它有点矫枉过正,因为使用 MediaWiki、Drupal 和 WordPress 之类的东西更容易设置。 很好的答案!非常感谢。我用 apache 浪费了 2 天的时间来让 websocket 工作——我失败了。然后我找到了这个答案,在切换到 nginx 后,一切几乎立即开始工作。【参考方案2】:

如果您在浏览器控制台中收到此错误客户端,您可以放心地忽略它 - 这意味着您的主机不支持 websockets 并且流星将回退到使用长轮询

meteor 应用程序部署到 heroku 或任何其他没有 websockets 的平台都会得到同样的错误


更新: 从流星 v0.6.4 开始,您现在可以设置环境变量 DISABLE_WEBSOCKETS 以防止发生这种尝试,如果您知道它会失败

https://github.com/meteor/meteor/blob/devel/History.md

If you set the DISABLE_WEBSOCKETS environment variable, browsers will not attempt to connect to your app using Websockets. Use this if you know your server environment does not properly proxy Websockets to reduce connection startup time.

【讨论】:

设置为 1?导出 DISABLE_WEBSOCKETS=1 ? 我做 DISABLE_WEBSOCKETS=true - 很确定任何值都可以使用流星语言 - 只需要设置为环境变量 我注意到,如果我在没有 websockets 的情况下通过蜂窝网络从移动设备访问它,图像无法加载...有没有办法在没有 websockets 的情况下解决这个问题? 讨厌投反对票,但你don't need to disable Websockets 投反对票 - 抱歉。这个答案被错误地标记为最佳答案,这不是真的。更好的答案来自 Dan Dascalescu,他描述了如何配置 nginx 以使 Websocket 工作。请参考这个答案:***.com/a/22750356/581768【参考方案3】:

关于 SEO:失败的 websocket(代码 400)也会阻止 Phantomjs 获得体面的页面加载(并且不会被终止)。

在我的例子中,来自 Dan 的新 Nginx 配置可以防止 websockets 失败并让 Phantomjs 加载页面。

【讨论】:

【参考方案4】:

在使用 AWS Elastic Load Balancer 时搜索此错误时发现此问题。设置环境变量是可行的,但更好的解决方案是在 ELB 上使用 TCP 协议而不是 HTTPS。仅供参考。

【讨论】:

感谢您分享精彩的见解。您能否详细说明为什么它更好,可能描述或参考设置的一些技术细节?

以上是关于使用 nginx 的 Meteor WebSocket 握手错误 400的主要内容,如果未能解决你的问题,请参考以下文章

使用 nginx 的 Meteor WebSocket 握手错误 400

015_NGINX作为WebSocket Proxy的设置

如何用服务器搭建一个Meteor国内包镜像源

websock使用

Android websock 应用

websock第一次连不上window