Добавить em-websocket в мое приложение с помощью puma

У меня есть приложение Ruby, работающее с Puma. Теперь я хотел добавить веб-сокет для трансляции запросов REST подключенным клиентам. Мне удалось создать сервер websocket с гемом em-websocket, просто добавив код в мой config.ru:

    require_relative 'config/environment'

require 'em-websocket'

Socket = EM.run {

  @channel = EM::Channel.new

  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 2929, :debug => true) do |ws|

    ws.onopen {
      sid = @channel.subscribe { |msg| ws.send msg }
      @channel.push "#{sid} connected!"

      ws.onmessage { |msg|
        @channel.push "blubb"
      }

      ws.onclose {
        @channel.unsubscribe(sid)
      }
    }

  end
}

run Rails.application

Проблема в том, что когда я запускаю 'rails server -b 0.0.0.0', веб-сокет работает, а мое приложение - нет. При подключении к localhost:3000 я получаю тайм-аут. Что я могу сделать, чтобы запустить их вместе?

Следующийвопрос: Как я могу транслировать через веб-сокет подключенным клиентам? Я думал о добавлении в контроллер запросов REST широковещательного метода. Это возможно?

1 ответ

Чтобы и Rails HTTP, и служба Websocket использовали один и тот же порт, у меня есть два варианта:

  1. Вы можете настроить прокси-сервер, который использует этот порт (возможно, nginx) и перенаправляет каждый запрос на соответствующий сервер приложений (например, Puma и EM).

  2. Вы можете использовать сервер Websocket+HTTP и запускать службы Websocket s в качестве промежуточного программного обеспечения в своем приложении HTTP (Rails) (т. Е. С помощью ActionCable, Faye или iodine + plezi).

Я предполагаю, что второе решение является более подходящим, хотя оно потребует от вас переноса кода с em-websockets к другому решению (например, Фэй или Йод / Плези).

Я должен отметить, что тесты показывают, что em-websocket может сломаться под нагрузкой, изнуряя процессор.

Я автор Йода, поэтому я предвзят, и считаю, что это лучшее решение, чем большинство альтернатив Ruby (и некоторые тесты согласны). Йод использует предложенную (и, вероятно, заброшенную) спецификацию Rack-Websocket, поэтому соединения HTTP и Websocket используют один и тот же сервер и реактор ввода-вывода, что обеспечивает лучшее управление ресурсами.

Однако вы также можете использовать Faye, который (аналогично текущей реализации ActionCable) захватывает сокет с HTTP-сервера и подключает его к отдельному реактору ввода-вывода после установления соединения Websocket.

Другие вопросы по тегам