Подтвердить что ты не робот

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.

4b9b3361

Ответ 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