使用puma将em-websocket添加到我的应用程序中

时间:2017-03-09 13:59:56

标签: ruby-on-rails ruby puma em-websocket

我有一个运行Puma的Ruby应用程序。现在我想添加一个websocket来向连接的客户端广播REST请求。我设法通过在我的config.ru中添加一些代码来创建一个带有em-websocket gem的websocket服务器:

    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'时,websocket正在运行,但我的应用程序却没有。当连接到localhost:3000我有时间。 我可以做些什么来一起运行它们?

跟进问题:如何通过websocket广播到已连接的客户端?我想添加到REST的控制器请求广播方法。这可能吗?

1 个答案:

答案 0 :(得分:0)

要让Rails HTTP和Websocket服务共享同一个端口,您有两个我知道的选项:

  1. 您可以设置使用该端口的代理(可能是nginx),并将每个请求转发给它的相应应用服务器(即Puma和EM)。

  2. 您可以使用Websocket + HTTP服务器并在HTTP(Rails)应用程序中运行Websockets服务作为中间件(即使用ActionCable,Faye或iodine + plezi)。

  3. 我假设第二种解决方案更加宽松,但它需要您将代码从em-websockets移植到其他解决方案(即Faye或Iodine / Plezi)。

    我应该注意到基准显示em-websocket might break down under stress, over-exhausting the CPU

    我是Iodine的作者,所以我有偏见,我相信这是一个比大多数Ruby替代品更好的解决方案(有些benchmarks同意)。 Iodine利用the proposed (and probably abandoned) Rack-Websocket specification,因此HTTP和Websocket连接共享相同的服务器和IO反应器,从而实现更好的资源管理。

    但是,您也可以使用Faye(类似于当前的ActionCable实现)从HTTP服务器劫持套接字,并在建立Websocket连接后将其附加到单独的IO反应器。