0

I'm trying to build a rails websocket application using em-websocket. I have placed the below code in a file config/initalizers/websocket.rb but when I run 'rails server' the application does not start. if I remove the code it starts fine. The same thing occurs on my local machine and server.

require 'eventmachine'
require 'em-websocket'

EventMachine.run {

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

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

    puts "Websocket started"
}

I get this console print out

=> Booting WEBrick
=> Rails 3.2.1 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Websocket started

If i remove the above code it starts fine and i get:

=> Booting WEBrick
=> Rails 3.2.1 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-12-21 04:19:52] INFO  WEBrick 1.3.1
[2012-12-21 04:19:52] INFO  ruby 1.9.3 (2012-04-20) [i386-mingw32]
[2012-12-21 04:19:52] INFO  WEBrick::HTTPServer#start: pid=1484 port=3000

Any ideas would be highly appreciated

user346443
  • 4,672
  • 15
  • 57
  • 80

2 Answers2

3

I haven't used this gem before, but it looks like you are starting a server in the initializer.

Execution is then paused on the main thread until your Websockets server returns control to it (which will presumably be when your websockets server is closed).

You probably want the server as a separate app, so you have a server that responds to HTTP (your Rails server), and a server that responds to the sockets (what your initializer file is the start of).

Joe Pym
  • 1,826
  • 12
  • 23
  • That's true, but, isn't it possible to have 1 app for both servers? So you only have to start 1 app, use 1 console, and deploy only once? – Tim Baas Feb 27 '13 at 08:58
  • Hmm. If you really want to do this, then I'd use Thin as your development web server. This is purely hypothesising, but Thin has an EventMachine backend (which Webrick doesn't), and so in theory, EventMachine.run should tie into the global Thin reactor loop? – Joe Pym Feb 28 '13 at 16:59
  • 1
    I just came across a gem called [foreman](https://www.google.nl/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CDQQFjAA&url=https%3A%2F%2Fgithub.com%2Fddollar%2Fforeman&ei=15NqUa-3B4nO0QXByoAY&usg=AFQjCNHI9ByOifzjRiX1pZPe9vk_OM7QUg&sig2=Yhweb3l7sx31qVyBQR7NpA&bvm=bv.45175338,d.d2k), you can bind a couple names to processes and run them all with `foreman start`.. What I did is put a server for sockets in a folder called `socket_server` and added the execution bashes for rails and the socket server (faye) to the foreman `Procfile`.. – Tim Baas Apr 14 '13 at 11:31
0

First solution:

  • Move websocket.rb to /config (Not inside initializers)
  • After running 'rails server' open another console.
  • Go to your_project_path/config/ and run 'ruby websocket.rb'

Second solution:

Put your code inside a Thread in order to avoid main thread blocking.

require 'eventmachine'
require 'em-websocket'

Thread.new { 

# Your websocket code

}
Karen Gonzalez
  • 664
  • 9
  • 17