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.