Rails6 Nginx Passenger ActionCable = websocket закрыт

#ruby-on-rails #nginx #websocket #actioncable

#ruby-on-rails #nginx #websocket #actioncable

Вопрос:

Существует аналогичный вопрос без ответа для Rails 5, но, поскольку я использую Rails 6, я спрашиваю снова.

У меня возникли некоторые проблемы с моим action cable в производственной среде. Среда разработки работает нормально.

Ошибка, которую нужно решить : WebSocket connection to 'wss://myapp.com/cable' failed: WebSocket is closed before the connection is established.

Я получаю эту ошибку несколько раз на консоли Chrome.

Стек

  • Ruby 2.6.5
  • Rails 6.0.3.2
  • Nginx 1.14.0

nginx.conf

 server {
listen 443 ssl;

  server_name *.myapp.com;
ssl_certificate /etc/letsencrypt/live/myapp.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem;

  root /home/deploy/myapp/current/public;

  passenger_enabled on;
  passenger_app_env production;

  location /cable {
    passenger_app_group_name myapp_websocket;
    passenger_force_max_concurrent_requests_per_process 0;
  }

  # Allow uploads up to 100MB in size
  client_max_body_size 100m;

  location ~ ^/(assets|packs) {
    expires max;
    gzip_static on;
  }
}
  

cable.yml

 development:
  adapter: redis

test:
  adapter: test

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: myapp_production
  

production.rb

   config.action_cable.url = 'wss://app.myapp.com/cable'
  config.action_cable.allowed_request_origins = [ 'https://app.myapp.com' ]
  

Эти строки постоянно повторяются в журнале:
журнал/production.log

 I, [2020-09-15T13:05:02.679580 #32158]  INFO -- : Finished "/cable/" [WebSocket] for xxx.xxx.133.88 at 2020-09-15 13:05:02  0000
I, [2020-09-15T13:05:03.791781 #32158]  INFO -- : [2c7c3ddf-e0d9-4f6b-80d5-ace193462c8a] Started GET "/cable" for xxx.xxx.133.88 at 2020-09-15 13:05:03  0000
I, [2020-09-15T13:05:03.792248 #32158]  INFO -- : [2c7c3ddf-e0d9-4f6b-80d5-ace193462c8a] Started GET "/cable/" [WebSocket] for xxx.xxx.133.88 at 2020-09-15 13:05:03  0000
I, [2020-09-15T13:05:03.792320 #32158]  INFO -- : [2c7c3ddf-e0d9-4f6b-80d5-ace193462c8a] Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPG
  

консоль браузера

 WebSocket connection to 'wss://app.myapp.com/cable' failed: WebSocket is closed before the connection is established.
  

Ответ №1:

Не могли бы вы прокомментировать эту строку в своем production.rb

 config.action_cable.url = 'wss://app.myapp.com/cable'
  

Кроме того, убедитесь, что в файле макета вашего представления есть эта строка, имя по умолчанию — application.html.erb.

Добавьте это в раздел head.

 <%= action_cable_meta_tag %>
  

В документации указано, что:

 8.3 Consumer Configuration

To configure the URL, add a call to action_cable_meta_tag in your HTML layout HEAD. This uses a URL or path typically set via config.action_cable.url in the environment configuration files.
  

Почему это необходимо в производстве, а не в разработке, не объяснено или не ясно.

Комментарии:

1. метод meta_tag добавит <meta name=»action-cable-url» content=»/ cable»> в ваш макет и предоставит URL-адрес action cable в вашем макете

2. Хорошо — но я думаю, я спрашиваю, что это делает, потому что в среде разработки это не требуется, а также я вижу, что сайт попадает на сервер даже без этого тега. И если это требуется, почему это не упоминается где-нибудь в коде Rails в сгенерированном по умолчанию приложении, в котором включен actioncable!

3. Да, это работает, но ответ требует объяснения того, ПОЧЕМУ это работает.

4. Это упоминается в документации rails: guides.rubyonrails.org/… Надеюсь, это ответит на ваш вопрос.

5. Кроме того, можете ли вы отметить этот вопрос полезным и правильным? Так что это поможет и другим пользователям