Rails + ActionCable +旅客 + AWS Elasticache (Redis) : 「接続が確立される前に WebSocket が閉じられる」を修正する方法。生産上?
概要
実稼働環境でアクション ケーブルを動作させるのにいくつか問題があります。開発環境は正常に動作しています。
解決すべきエラー: 「wss://myapp.com/cable」への WebSocket 接続が失敗しました: 接続が確立される前に WebSocket が閉じられました。
Chrome のコンソールでこのエラーが複数回発生します。
スタック
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;
}
}
ケーブル.yml
production:
adapter: redis
url: redis://myapp.grzdsm.0001.euw1.cache.amazonaws.com:6379
プロダクション.rb
config.action_cable.url = "wss://myapp.com/cable"
config.action_cable.allowed_request_origins = ["https://myapp.com", "myapp.com"]
ルート.rb
mount ActionCable.server => '/cable'
通知チャンネル.rb
class NotificationChannel < ApplicationCable::Channel
def subscribed
stream_from "notification"
end
def unsubscribed
end
end
接続.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
チャンネル.rb
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
ケーブル.js
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
通知.コーヒー
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 が閉じられました。
何か手がかりがあれば本当に感謝します、ありがとう!
解決策
config/environments/production.rb ファイル内の「wss://…」を「ws://…」に変更する必要がある場合があります。