español - sinatra ruby github
Transmisión de datos desde la aplicación Sinatra/Rack (4)
Estoy tratando de transmitir datos de texto (XML / JSON) desde una aplicación Ruby (1.9.1p378) Sinatra (1.0) Rack (1.2.1). Las soluciones sugeridas (p. Ej. ¿Existe una forma de descargar html al cable en Sinatra ) no parecen funcionar? El servidor solo bloquea cuando cedo elementos de una corriente infinita (p. Ej., De %w(foo bar).cycle
). Intenté webrick
y thin
como servidores.
¿Alguna sugerencia sobre cómo hacer esto? ¿Debo usar http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html y, de ser así, cómo lo usaría en mi aplicación?
A partir de Sinatra 1.3, también podría usar la nueva API de transmisión:
get ''/evented'' do
stream(:keep_open) do |out|
EventMachine::PeriodicTimer.new(1) { out << "#{Time.now}/n" }
end
end
Como mencionó Colin, Goliath puede transmitir datos de respuesta, así como entrantes (grandes archivos subidos). Hay un ejemplo en el repositorio para transmitir datos al cliente: https://github.com/postrank-labs/goliath/blob/master/examples/stream.rb
En lugar de un temporizador, puede conectar fácilmente cualquier otro flujo de datos para enviar datos al cliente. Por ejemplo, puede conectar una cola AMQP, o cualquier otra cola de mensajes directamente a Goliath y dejar que actúe como una interfaz HTTP para esos datos.
Definitivamente deberías echarle un vistazo al servidor web Goliath capaz de instalar en rack. Es compatible con la transmisión fuera de la caja. Lo estoy usando para un api de streaming de estilo firehose.
Goliath es tanto un servidor de aplicaciones como un marco ligero diseñado para cumplir los siguientes objetivos: procesamiento completamente asíncrono, soporte de middleware, configuración simple, alto rendimiento y, posiblemente, el código más legible y mantenible.
Ni Webrick ni Thin soportan la transmisión de esa manera. Podrías probar Mestizo o Unicornio. Si desea utilizar Thin o Rainbows !, debe conectarse al bucle de eventos para lograr la transmisión:
require ''sinatra''
class Stream
include EventMachine::Deferrable
def initialize
@counter = 0
end
def each(&block)
if @counter > 10
succeed
else
EM.next_tick do
yield counter
each(&block)
end
end
end
end
get ''/'' do
Stream.new
end
Recientemente escribí una implementación de EventSource de esa manera:
require ''sinatra''
class EventStream
include EventMachine::Deferrable
def each
count = 0
timer = EventMachine::PeriodicTimer.new(1) do
yield "data: #{count += 1}/n/n"
end
errback { timer.cancel }
end
end
get ''/'' do
EventMachine.next_tick do
request.env[''async.callback''].call [
200, {''Content-Type'' => ''text/event-stream''},
EventStream.new ]
end
[-1, {}, []]
end
Si desea utilizar Webrick para transmisión: here hay un parche.