ruby sinatra websocket rack eventmachine

ruby - ¿Algún éxito con Sinatra trabajando en conjunto con EventMachine WebSockets?



rack (5)

He estado usando Sinatra por algún tiempo y me gustaría agregar algunas funciones en tiempo real a mi aplicación web al presionar los datos a través de websockets.

He utilizado con éxito el gem ''em-websocket'' por sí mismo, pero no he podido escribir un archivo ruby ​​que tenga un servidor web sinatra Y un servidor web-socket.

¡He intentado hacer girar la carrera! o comienza! métodos desactivados en hilos separados sin éxito.

¿Alguien ha conseguido que esto funcione?

Quiero tenerlos en el mismo archivo que pueda y luego compartir las variables entre los dos servidores.

¡Gracias!


FYI, también puedes usar las aplicaciones de Padrino con EventMachine (ya que son subconjuntos de aplicaciones de Sinatra):

require ''rubygems'' require ''eventmachine'' require ''padrino-core'' require ''thin'' require ::File.dirname(__FILE__) + ''/config/boot.rb'' EM.run do Thin::Server.start Padrino.application, ''0.0.0.0'', 3000 end

Saludos, Mike


Gracias Konstantin ... ¡eso funcionó! Tuve que modificar tu código un poco. Agregué comentarios donde lo cambié.

-poul

require ''rubygems'' # <-- Added this require require ''em-websocket'' require ''sinatra/base'' require ''thin'' EventMachine.run do # <-- Changed EM to EventMachine class App < Sinatra::Base get ''/'' do return "foo" end end EventMachine::WebSocket.start(:host => ''0.0.0.0'', :port => 8080) do |ws| # <-- Added |ws| # Websocket code here ws.onopen { ws.send "connected!!!!" } ws.onmessage { |msg| puts "got message #{msg}" } ws.onclose { ws.send "WebSocket closed" } end # You could also use Rainbows! instead of Thin. # Any EM based Rack handler should do. App.run!({:port => 3000}) # <-- Changed this line from Thin.start to App.run! end


He estado usando sinatra-websocket . Le permite ejecutar el servidor websocket en el mismo proceso y en el mismo puerto que Sinatra.

Descargo de responsabilidad: soy el mantenedor.

require ''sinatra'' require ''sinatra-websocket'' set :server, ''thin'' set :sockets, [] get ''/'' do if !request.websocket? erb :index else request.websocket do |ws| ws.onopen do ws.send("Hello World!") settings.sockets << ws end ws.onmessage do |msg| EM.next_tick { settings.sockets.each{|s| s.send(msg) } } end ws.onclose do warn("websocket closed") settings.sockets.delete(ws) end end end end __END__ @@ index <html> <body> <h1>Simple Echo & Chat Server</h1> <form id="form"> <input type="text" id="input" value="send a message"></input> </form> <div id="msgs"></div> </body> <script type="text/javascript"> window.onload = function(){ (function(){ var show = function(el){ return function(msg){ el.innerHTML = msg + ''<br />'' + el.innerHTML; } }(document.getElementById(''msgs'')); var ws = new WebSocket(''ws://'' + window.location.host + window.location.pathname); ws.onopen = function() { show(''websocket opened''); }; ws.onclose = function() { show(''websocket closed''); } ws.onmessage = function(m) { show(''websocket message: '' + m.data); }; var sender = function(f){ var input = document.getElementById(''input''); input.onclick = function(){ input.value = "" }; f.onsubmit = function(){ ws.send(input.value); input.value = "send a message"; return false; } }(document.getElementById(''form'')); })(); } </script> </html>


Me encontré con este proyecto web websocket-rack github que básicamente es un em-websocket rackified y en realidad funcionó muy bien con una aplicación Sinatra. Aquí está mi config.ru:

require ''rubygems'' require ''rack/websocket'' require ''sinatra/base'' class WebSocketApp < Rack::WebSocket::Application # ... end class SinatraApp < Sinatra::Base # ... end map ''/ws'' do run WebSocketApp.new end map ''/'' do run SinatraApp end

¡Que te diviertas!
Colin


No lo probé, pero no debería ser demasiado difícil:

require ''em-websocket'' require ''sinatra/base'' require ''thin'' EM.run do class App < Sinatra::Base # Sinatra code here end EM::WebSocket.start(:host => ''0.0.0.0'', :port => 3001) do # Websocket code here end # You could also use Rainbows! instead of Thin. # Any EM based Rack handler should do. Thin::Server.start App, ''0.0.0.0'', 3000 end

Además, Cramp tiene una implementación de websocket que funciona directamente con Thin / Rainbows. es posible que pueda extraer, por lo que ni siquiera necesitará ejecutar el servidor en otro puerto.