ActionCable 不再在生产环境中工作

ActionCable no longer working in production environment

我有一个 Rails 5 应用程序,它使用 Action Cable 实现 websocket 功能。

在我的开发环境中,一切正常,浏览器客户端成功连接到 Action Cable 个频道。

在我的生产环境中,Action Cable 曾在某个时候工作,但随后突然停止运行,没有任何直接的明显原因。

如果我将 RAILS_ENV 更改为 production 而 运行 我的开发机器 Action Cable 上的应用程序运行正常。 运行实际生产机器上的应用程序虽然基本环境相同,但似乎有所不同。

我在Chrome控制台看到的具体错误:

mydomain.com/:1 WebSocket connection to 'wss://mydomain.com/cable' failed: WebSocket is closed before the connection is established。我在其他浏览器中遇到了类似的错误,因此它似乎与浏览器无关。我在测试时禁用了所有广告拦截器,以确保它们不会干扰。

Development.rb ENV 相关设置:

config.action_cable.url = "ws://localhost:#{port}/cable"

Production.rb ENV 相关设置:

hostname = ENV.fetch('HOSTNAME')
  port = ENV.fetch('PORT')
  base_url = "#{hostname}:#{port}"

  config.action_cable.url = "wss://#{hostname}/cable"
  config.action_cable.allowed_request_origins = ["https://#{base_url}", "https://#{hostname}"]

我使用 Puma 作为网络服务器。 Web 服务器提供安装了有效证书的 SSL 连接。在生产机器上,Puma 在端口 3000 上提供应用程序,但它被转发到路由器中的端口 443

与 运行 我的开发机器和生产机器上的应用程序的唯一显着区别是在生产机器中使用 SSL。

根据你的问题陈述

  • 您的开发环境可以正常工作,因为您已将其设置为处理不安全的 Web 流量,但在您的生产环境中设置为处理安全流量。

Development.rb ENV相关设置:

config.action_cable.url = "ws://localhost:#{port}/cable"

Production.rb ENV相关设置:

 config.action_cable.url = "wss://#{hostname}/cable"  

根据您的网络设置,您已将 SSL 端口重定向配置为端口 3000 并为来自 PUMA rb 服务器的 Web 请求提供服务。

现在我在这里看到的问题是 wss://#{hostname} 将尝试在默认端口 443 上侦听安全流量,而不是您的重定向端口 3000

我现在可以确定这是一个错误,可能在 Rails/ActionCable 本身。这得到了其他报告的证实,正如我曾说过的那样,它工作得很好,那是我使用 Rails 5.0.0.1 的时候。当我更新到 5.0.1 时它坏了,它在 5.0.2 上仍然坏了。我正在 Rails 项目的 GitHub issue tracker 上打开一个问题。

2017 年 7 月编辑:Rails 确实改变了它读取和写入 Rack 套接字的方式,但是您使用的实际网络服务器软件需要支持这些非阻塞读取和写入方法。就我而言,Puma 当时没有,因此 websockets 不起作用。对于 Puma,现在有一个新版本解决了这个问题。