对于所有关注的人,希望这会有所帮助。
截至我撰写本文时(2018 年 10 月),您似乎根本无法在 Cloudfront 后面使用 ActionCable。 CF 将丢弃升级标头,这将阻止建立安全套接字连接。
我们的设置是 CF -> 应用程序负载均衡器 (ALB) -> EC2。在 AWS 方面,我们首先创建了一个直接指向同一个 ALB 并完全绕过 CF 的子域 (socket.example.com)。请注意,Classic Load Balancer 绝对不起作用。您只能使用 ALB。
仅此一项并不能解决问题。在您的 Rails 配置中,您必须将以下行添加到您的 production.rb:
config.action_cable.url = 'wss://socket.example.com:28080/cable'
config.action_cable.allowed_request_origins = ['https://example.com'] # Not the subdomain
您可能还需要更新您的 CSP 以将 wss://socket.example.com/cable 包含在 connect_src 中。
如果此时您收到有关升级失败的消息,则需要确保您的 NGINX 配置正确。 This answer may help.
您还需要在您的cable.js 中反映此更改。以下 sn-p 对我来说适用于本地开发和生产,但您可能需要更改它。我写它时考虑到了 pre-ES6,因为这个文件在我们的配置中从来没有遇到过 Babel。
(function() {
this.App || (this.App = {})
var wsUrl
if(location.host.indexOf('localhost') != -1) {
wsUrl = '/cable'
} else {
var host = location.host
var protocol = location.protocol
wsUrl = protocol + '//socket.' + host + '/cable'
}
App.cable = ActionCable.createConsumer(wsUrl)
}).call(this)
这可能就是您所需要的,具体取决于您的身份验证方案。但是,我使用的是在主应用程序和 ActionCable 之间共享的 cookie,这导致了一个棘手的错误。连接看起来是正确的,但实际上会失败,并且 ActionCable 会每 10 秒重试一次。最后一步是确保设置的身份验证 cookie 可以跨套接字子域工作。我这样更新了我的 cookie:
cookies.signed[:cookie_name] = {
value: payload,
domain: ['.socket.example.com', '.example.com']
# Some people have to specify tld_length, but I was fine without it
}