Rails + ActionCable + Passenger + AWS Elasticache (Redis):如何修复“WebSocket 在建立连接之前关闭。”在生产?

Posted

技术标签:

【中文标题】Rails + ActionCable + Passenger + AWS Elasticache (Redis):如何修复“WebSocket 在建立连接之前关闭。”在生产?【英文标题】:Rails + ActionCable + Passenger + AWS Elasticache (Redis) : how to fix 'WebSocket is closed before the connection is established.' on production? 【发布时间】:2019-09-23 22:10:33 【问题描述】:

我在生产环境中使用动作电缆时遇到了一些麻烦。 开发环境运行良好。

要解决的错误: 与“wss://myapp.com/cable”的 WebSocket 连接失败:在建立连接之前 WebSocket 已关闭。

我在 Chrome 的控制台上多次收到此错误。

堆栈

Ruby 2.3.0 Rails 5.0.7.2 nginx 1.10.1 客运 5.0.30 Redis 5.0.3(在 AWS Elasticache 上)

nginx.conf

server 
  listen 443 ssl;
  server_name myapp.com *myapp.com;
  root /home/ubuntu/myapp/current/public;
  ssl_certificate ...;
  ssl_certificate_key ...;
  passenger_enabled on;
  passenger_min_instances 1;
  ...

  location /cable 
    passenger_app_group_name my_app_action_cable;
    passenger_force_max_concurrent_requests_per_process 0;
  

cable.yml

production:
  adapter: redis
  url: redis://myapp.grzdsm.0001.euw1.cache.amazonaws.com:6379

production.rb

config.action_cable.url = "wss://myapp.com/cable"
config.action_cable.allowed_request_origins = ["https://myapp.com", "myapp.com"]

routes.rb

mount ActionCable.server => '/cable'

notification_channel.rb

class NotificationChannel < ApplicationCable::Channel

  def subscribed
    stream_from "notification"
  end

  def unsubscribed
  end

end

connection.rb

module ApplicationCable
  class Connection < ActionCable::Connection::Base
  end
end

channel.rb

module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end

cable.js

//= require action_cable
//= require_self
//= require_tree ./channels

(function() 
  this.App || (this.App = );

  App.cable = ActionCable.createConsumer();

).call(this);

notification.coffee

App.notification = App.cable.subscriptions.create "NotificationChannel",
  connected: ->
    console.log("connected");

  disconnected: ->
    console.log("disconnected");

  received: (data) ->
    console.log("received");

我的日志显示 websocket 连接成功

I, [2019-05-06T11:00:57.688540 #4986]  INFO -- : Finished "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:00:57 +0200
I, [2019-05-06T11:01:09.799045 #4986]  INFO -- : Started GET "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:01:09 +0200
I, [2019-05-06T11:01:09.799154 #4986]  INFO -- : Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [2019-05-06T11:01:09.803010 #4986]  INFO -- : Registered connection (Z2lkOi8veXBqL1VzZXIvMjkx)
I, [2019-05-06T11:01:20.541988 #4986]  INFO -- : Finished "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:01:20 +0200
I, [2019-05-06T11:01:21.784567 #4986]  INFO -- : Started GET "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:01:21 +0200
I, [2019-05-06T11:01:21.784672 #4986]  INFO -- : Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [2019-05-06T11:01:21.788734 #4986]  INFO -- : Registered connection (Z2lkOi8veXBqL1VzZXIvMjkx)
I, [2019-05-06T11:01:43.768741 #4986]  INFO -- : Finished "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:01:43 +0200
I, [2019-05-06T11:01:44.784226 #4986]  INFO -- : Started GET "/cable/" [WebSocket] for 144.85.191.180 at 2019-05-06 11:01:44 +0200
I, [2019-05-06T11:01:44.784333 #4986]  INFO -- : Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [2019-05-06T11:01:44.788154 #4986]  INFO -- : Registered connection (Z2lkOi8veXBqL1VzZXIvMjkx)

Redis 监视器显示订阅和取消订阅

1557133304.788584 [0 172.30.1.177:59731] "subscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133326.654308 [0 172.30.1.177:59731] "unsubscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133327.910010 [0 172.30.1.177:59731] "subscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133349.255254 [0 172.30.1.177:59731] "unsubscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133351.183697 [0 172.30.1.177:59731] "subscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133356.974099 [0 172.30.1.177:59731] "unsubscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133357.707420 [0 172.30.1.177:59731] "subscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"
1557133371.886670 [0 172.30.1.177:59731] "unsubscribe" "action_cable/Z2lkOi8veXBqL1VzZXIvMjkx"

但我仍然收到此错误:与“wss://myapp.com/cable”的 WebSocket 连接失败:在建立连接之前 WebSocket 已关闭。

任何线索将不胜感激,谢谢!

【问题讨论】:

我无法连接动作电缆,它没有打电话给我,[2019-05-06T11:00:57.688540 #4986] INFO -- : Finished "/cable/" [WebSocket] for 144.85 .191.180 at 2019-05-06 11:00:57 +0200 I, [2019-05-06T11:01:09.799045 #4986] INFO -- : Started GET "/cable/",而 production.rb 的设置相同和所有。你能告诉我为什么它没有调用 /cable 与服务器负载。 我在 Rails 6 中遇到同样的问题 - 我要提出一个新问题。 【参考方案1】:

您可能需要在 config/environments/production.rb 文件中将 'wss://...' 更改为 'ws://...'

【讨论】:

以上是关于Rails + ActionCable + Passenger + AWS Elasticache (Redis):如何修复“WebSocket 在建立连接之前关闭。”在生产?的主要内容,如果未能解决你的问题,请参考以下文章

Rails 5 - ActionCable - 无法升级到 WebSocket

ActionCable 频道在 Rails 插件之外无法访问

在 Heroku 上部署 ActionCable (Rails 5 beta4)

在 Rails 中广播消息时未调用 ActionCable 频道

Websocket握手期间的Rails ActionCable错误

Rails 5.1 - ActionCable没有更新?