WebSocket機能にAction Cable
を使用するRails 5アプリがあります。
私の開発環境では、すべてが期待どおりに機能し、ブラウザクライアントは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サーバーとして使用しています。 Webサーバーは、有効な証明書がインストールされているSSL接続を提供します。本番マシンでは、Pumaはポート3000
でアプリケーションを提供しますが、これはルーターのポート443
に転送されます。
開発マシンと本番環境でアプリを実行する場合の唯一の顕著な違いは、本番環境ではSSLが使用されることです。
これはおそらくRails/ActionCable自体のバグであると安全に結論付けることができます。これは他のレポートによって裏付けられており、ある時点で正常に機能したと言ったように、これはRails 5.0.0.1
を使用したときです。5.0.1
に更新したときに壊れて5.0.2
で壊れたままです。GitHubで問題を開いています 問題追跡システム Railsプロジェクト。
2017年7月の編集:Railsは、Rackソケットの読み取りと書き込みの方法に関して何かを変更しましたが、使用する実際のWebサーバーソフトウェアは、これらの非ブロッキング読み取りおよび書き込みメソッドをサポートする必要があります。私の場合、 Pumaは当時機能していなかったため、WebSocketは機能しませんでした。Pumaの場合、この問題の回避策を含む新しいリリースがあります。
問題の説明に従って
Development.rb ENV関連のセットアップ:
config.action_cable.url = "ws://localhost:#{port}/cable"
Production.rb ENV関連のセットアップ:
config.action_cable.url = "wss://#{hostname}/cable"
ネットワーク設定に従って、ポート3000へのSSLポートリダイレクトを構成し、PUMArbサーバーからのWeb要求を処理します。
今私がここで見ている問題はwss://#{hostname}
リダイレクトされたポート3000ではなく、デフォルトのポート443で安全なトラフィックをリッスンしようとします