Запуск ActionCable за Cloudfront - PullRequest
       37

Запуск ActionCable за Cloudfront

0 голосов
/ 23 октября 2018

Мы настроили Cloudfront перед нашим приложением, но, к сожалению, оно удаляет заголовок Upgrade, необходимый для запуска ActionCable.

Мы хотели бы иметь другой поддомен, который указывает на те же серверы, но обходит Cloudfront (socket.site.com, например).Мы сделали это, и это несколько работает, но кажется, что постоянное соединение не может быть установлено.ActionCable продолжает попытки установить соединение каждые 10 секунд и, кажется, не может удерживать соединение открытым:

enter image description here

Любые рекомендации, связанные с Cloudfront или другими доменами для ActionCableценится.

1 Ответ

0 голосов
/ 24 октября 2018

Всем, кто следует, надеюсь, это поможет.

На момент написания этой статьи (октябрь 2018 г.), похоже, что вы вообще не можете использовать ActionCable за Cloudfront.CF откажется от заголовка обновления, что предотвратит установление безопасного сокета.

Наша установка была CF -> Application Load Balancer (ALB) -> EC2.Что касается AWS, мы начали с создания поддоменов (socket.example.com), которые указывали бы прямо на тот же ALB и полностью обходили CF.Обратите внимание, что классические балансировщики нагрузки абсолютно не будут работать.Вы можете использовать только ALB.

Это само по себе не решило проблему.В вашей конфигурации Rails вы должны добавить следующие строки в production.rb:

config.action_cable.url = 'wss://socket.example.com:28080/cable'
config.action_cable.allowed_request_origins = ['https://example.com'] # Not the subdomain

Возможно, вам также потребуется обновить CSP, включив wss://socket.example.com/cable для connect_src.

Если в этот момент вы получаете сообщение о невозможности обновления, вам необходимо убедиться, что ваша конфигурация NGINX верна. Этот ответ может помочь .


Вам также необходимо отразить это изменение в вашем cable.js.Этот следующий фрагмент работает для меня как с локальной разработкой, так и с производством, но вам, возможно, придется изменить его.Я написал это с пред-ES6, потому что этот файл никогда не попадал в Babel в нашей конфигурации.

(function() {
  this.App || (this.App = {})

  var wsUrl
  if(location.host.indexOf('localhost') != -1) {
    wsUrl = '/cable'
  } else {
    var host = location.host
    var protocol = location.protocol
    wsUrl = protocol + '//socket.' + host + '/cable'
  }

  App.cable = ActionCable.createConsumer(wsUrl)

}).call(this)

Это может быть все, что вам нужно, в зависимости от вашей схемы аутентификации.Тем не менее, я использовал файлы cookie, общие для основного приложения и ActionCable, и это вызвало сложную ошибку.Казалось бы, соединение установлено правильно, но на самом деле произойдет сбой, и ActionCable будет повторять каждые 10 секунд.Последний шаг состоял в том, чтобы гарантировать, что устанавливаемые файлы cookie авторизации будут работать через поддомен сокета.Я обновил свой файл cookie следующим образом:

cookies.signed[:cookie_name] = {
  value: payload,
  domain: ['.socket.example.com', '.example.com']
  # Some people have to specify tld_length, but I was fine without it
}
...