ActionCable больше не работает в производственной среде
У меня есть приложение 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"
Производственная программа ENV, связанная с 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
как веб-сервер. Веб-сервер обслуживает SSL-соединение, для которого установлен действительный сертификат. На производственной машине Puma обслуживает приложение на порту 3000
, но оно перенаправляется на порт 443
в маршрутизаторе.
Единственная заметная разница с запуском приложения на моей машине и производственной машине - это то, что в производстве используется SSL.
Ответы
Ответ 1
Теперь я могу спокойно заключить, что это ошибка, возможно, в Rails/ActionCable. Это подтверждается другими отчетами, и, как я сказал, в какой-то момент он работал нормально, это было, когда я использовал Rails 5.0.0.1
. Когда я обновился до 5.0.1
, он сломался, и он остался сломанным на 5.0.2
. Я открываю проблему в GitHub трекер ошибок проекта Rails.
Изменить июль 2017: Rails что-то изменило в отношении того, как он читает и записывает в сокет Rack, однако используемое вами программное обеспечение веб-сервера должно поддерживать эти неблокирующие методы чтения и записи. В моем случае, Puma в то время не было, поэтому веб-порты не работали. Для Puma теперь появился новый выпуск с обходным решением для этой проблемы.
Ответ 2
В соответствии с вашим выражением о проблеме
- Ваша среда разработки работает, потому что вы настроили ее на работу с небезопасным веб-трафиком, но на вашей производственной среде настроено управление безопасным трафиком.
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.
Теперь проблема, которую я вижу здесь, wss://#{hostname}
будет пытаться прослушивать по умолчанию порт 443 для безопасного трафика, а ваш перенаправленный порт 3000