【问题标题】:nginx proxy for Javascript WebSocket clientJavascript WebSocket 客户端的 nginx 代理
【发布时间】:2017-05-31 18:41:59
【问题描述】:

我在本地主机上运行 nginx,提供静态 html/css/js 文件。它为所需的 RESTful 数据库服务代理到远程服务器。我还需要设置 nginx 以代理到远程 websocket 服务器,但所有尝试都失败了。

如果我像这样对 websocket 服务器 url 进行硬编码,Javascript 客户端就可以工作:

socket = new WebSocket("ws://50.29.123.83:9030/something/socket");

显然,这不是最佳解决方案,我应该能够使用 location.host 和代理来到达同一位置。我使用以下配置了 nginx:

http {
  ...
  upstream websocket {
    server 50.29.123.83:9030;
    }
}

sever {
  ...
  location /the_socket/ {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
  }
}

然后将客户端代码更新为:

socket = new WebSocket("ws://" + location.host + "/the_socket/something/socket");

这会失败并出现以下错误:

到 'ws://localhost/the_socket/something/socket' 的 WebSocket 连接 失败:WebSocket 握手期间出错:意外的响应代码: 404

我做错了什么?

  • 更改 IP 和端口号以保护无辜者

【问题讨论】:

  • 看起来location.host 引用了localhost,这可能是指向本地的nginx 实例,但是如果它们是相同的东西,那么还有location.host 也不包括的问题url中的端口
  • location.host 正在引用本地 nginx 正在运行的本地主机。端口通过上游服务器声明在 proxy_pass 中指定。
  • 您将使用/the_socket/something/socket 访问远程服务器,因为您没有尝试删除前缀。
  • @RichardSmith 您能否详细说明一下,我不确定您指的是什么。谢谢。

标签: javascript nginx websocket proxy


【解决方案1】:

您的代理语句会将 URI 未经修改地传递给上游服务器。也就是说文本/the_socket 仍将附加到 URI 的开头。

如果您希望 proxy_pass 修改 URI 并删除 location 值 - 您应该在 proxy_pass 语句中添加一个 URI。例如:

location /the_socket/ {
    proxy_pass http://websocket/;
    ...
}

详情请见this document

【讨论】:

  • 谢谢你,理查德!