em-websocket icon indicating copy to clipboard operation
em-websocket copied to clipboard

There is no way to run EM::WebSocket listener EM-way

Open samuil opened this issue 13 years ago • 7 comments

What I would like to achieve is writing my own module/class containing onopen, onmessage and other events' handlers, include EM::WebSocket in it and just run EM.start_server providing this module as parameter. This way it is possible to keep code quite readable and clean, while having multiple listeners plugged in single EM instance.

Right now I was unable to find any clean way of using EM::WebSocket gem without cluttering my EventMachine::run block with code specific to supporting this one listener.

I'm willing to refactor parts of em-websocket code, while keeping support for current EM::WebSocket.start method, but I'd like to hear feedback about the idea first.

samuil avatar May 29 '12 10:05 samuil

This does what you're looking for: https://github.com/postrank-labs/goliath/blob/master/lib/goliath/websocket.rb

igrigorik avatar May 29 '12 14:05 igrigorik

Still -- EventMachine is quite widely used, so having well-written WebSockets implementation might help some projects. What do you think about porting solution introduced in Goliath to this gem?

samuil avatar May 29 '12 14:05 samuil

I'm still not sure what you're after.. If you have a specific proposal, outline it and we can discuss it. "Well written" is ambiguous :-)

igrigorik avatar May 29 '12 14:05 igrigorik

I'm only referring to defining you own WS handlers as modules, maybe suggesting that it is not "well written" could sound a bit nasty ;)

I don't have currently whole idea of internal implementation. I have in mind interface that I would like to use in my application, that would be analogous to other handlers that I have written. Solution provided by Goliath seems to be one way to do it.

samuil avatar May 29 '12 15:05 samuil

Providing a subclassed EM::WebSocket::Connection might be closer to what you're looking for. This isn't the documented usage of the library, but it works absolutely fine.

Here's what the example echo client would look like (I may commit this to the examples folder for reference):

class MyWSConnection < EM::WebSocket::Connection
  def trigger_on_open
    send "Hello Client!"
  end

  def trigger_on_message(msg)
    send "Pong: #{msg}"
  end

  def trigger_on_close(event = {})
    puts "WebSocket closed"
  end

  def trigger_on_error(reason)
    puts "Error: #{e.message}"
  end
end

EM.run {
  EM.start_server('0.0.0.0', 8080, MyWSConnection, :debug => true)
}

mloughran avatar May 29 '12 15:05 mloughran

This is solution I was using up to now, but I considered it a bit "hacky" -- as long as it is not documented it can't be safely used as further gem development could possibly break it. Using EM::WebSocket as a mixin, and keeping consistent names of methods (without trigger_ prefix) seems a bit cleaner for me.

samuil avatar May 29 '12 15:05 samuil

I jusr ran into this situation, I think it would be nice to have em-websocket abstracted to so one can use it like a class and start it with EM.start_server('0.0.0.0', 8080, myWsHandlerClass). The main advantage is modularization as we don't have to write all the code inside the do |ws|

...

end block.

betolink avatar Sep 11 '13 20:09 betolink