Search code examples
ruby-on-railsrubyeventmachineem-websocket

EventMachine in Rails - where to put run loop?


I am trying to get an EventMachine server that runs when I run my rails server and not as a separate process.

So for example, using the simple server example from here (em-websocket) you get the following (standalone?) ruby code:

EventMachine.run {

EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
    ws.onopen {
      puts "WebSocket connection open"

      # publish message to the client
      ws.send "Hello Client"
    }

    ws.onclose { puts "Connection closed" }
    ws.onmessage { |msg|
      puts "Recieved message: #{msg}"
      ws.send "Pong: #{msg}"
    }
end
}

Assuming I just ran the command "rails new em-example" where does the above code go in my rails 3 app?

I would imagine the above code should ideally run in a separate thread (or fiber..?), but am unsure how that looks.

I've seen that this should be easy if using 'thin' as my webserver. Heroku seems to use this by default and I've installed the 'thin' gem so I can test it out locally as well.


Solution

  • You'll probably want to toss your code into an initializer. John Nunemaker posted some really interesting info about firing up EventMachine under Passenger in a Sinatra app, and I'd imagine it would work fairly similarly for you.

    That said, it sounds like you're just trying to get a web sockets server working with Heroku. In theory youd think running on the Cedar stack and adding a new process type to your Procfile for your EM based Websockets server would get it working. That would look something like:

    web:         bundle exec rails server -p $PORT
    websocket:   bundle exec script/websocket_server $PORT
    

    With script/websocket_server being your app's socket server script that can handle a custom port argument.

    Unfortunately, though, Heroku doesn't support Websockets yet, as outlined here, so a Procfile solution most likely wouldn't work.