Добавить 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 использовали один и тот же порт, у меня есть два варианта:
Вы можете настроить прокси-сервер, который использует этот порт (возможно, nginx) и перенаправляет каждый запрос на соответствующий сервер приложений (например, Puma и EM).
Вы можете использовать сервер Websocket+HTTP и запускать службы Websocket s в качестве промежуточного программного обеспечения в своем приложении HTTP (Rails) (т. Е. С помощью ActionCable, Faye или
iodine
+plezi
).
Я предполагаю, что второе решение является более подходящим, хотя оно потребует от вас переноса кода с em-websockets
к другому решению (например, Фэй или Йод / Плези).
Я должен отметить, что тесты показывают, что em-websocket
может сломаться под нагрузкой, изнуряя процессор.
Я автор Йода, поэтому я предвзят, и считаю, что это лучшее решение, чем большинство альтернатив Ruby (и некоторые тесты согласны). Йод использует предложенную (и, вероятно, заброшенную) спецификацию Rack-Websocket, поэтому соединения HTTP и Websocket используют один и тот же сервер и реактор ввода-вывода, что обеспечивает лучшее управление ресурсами.
Однако вы также можете использовать Faye, который (аналогично текущей реализации ActionCable) захватывает сокет с HTTP-сервера и подключает его к отдельному реактору ввода-вывода после установления соединения Websocket.