2010-09-08 15 views
22

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 (por ejemplo, Is there a way to flush html to the wire in Sinatra) no parecen funcionar: el servidor solo bloquea cuando cedo elementos de algún flujo infinito (por ejemplo, desde %w(foo bar).cycle). Intenté webrick y thin como servidores.Transmisión de datos desde la aplicación Sinatra/Rack

¿Alguna sugerencia para hacer esto? ¿Debería usar http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html y de ser así cómo lo usaría en mi aplicación?

Respuesta

19

Ni Webrick ni Thin admiten la transmisión de esa manera. Podrías probar Mongrel o Unicornio. Si desea utilizar delgada o arco iris !, usted tiene que enganchar en el bucle de eventos con el fin de lograr el streaming:

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 

Hace poco escribió una aplicación 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 quieres para usar Webrick for Streaming: here es un parche.

+2

Delgado tiene la ventaja de ser capaz de responder a otras solicitudes durante la transmisión. –

+0

Confirmado que funciona con Mongrel. Gracias Konstantin! – yawn

5

Definitivamente debe echar un vistazo a la Goliath web server rack-able. Es compatible con la transmisión fuera de la caja. Lo estoy usando para una aplicación de transmisión de estilo firehose.

Goliat es tanto un servidor de aplicaciones y un marco ligero diseñado para satisfacer los siguientes objetivos: totalmente procesamiento asíncrono, middleware de soporte, de configuración sencilla, de alto rendimiento, y podría decirse que la mayoría importante, fácil de leer y código mantenible.

+0

proyecto muy interesante! ¡Gracias, pista! – yawn

7

Como mencionó Colin, Goliath puede transmitir datos de respuesta, así como los recibidos (grandes cargas de archivos). 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 otra secuencia de datos para enviar datos al cliente. Por ejemplo, puede conectar una cola de AMQP, o cualquier otra cola de mensajes directamente a Goliath y dejar que actúe como una interfaz HTTP a esa información.

+0

¿Hay alguna comunidad para goliath en alguna parte? Todo el proyecto parece ser bastante innovador y no estoy seguro de algunas cosas como soporte para fragmentación y la identificación de solicitudes en devoluciones de llamada ... – yawn

+1

La lista de distribución es un gran lugar para comenzar: https: // groups. google.com/forum/#!forum/goliath-io - hay un buen grupo de personas que lo está viendo. Algunas de las aplicaciones más interesantes que se están construyendo con Goliath lamentablemente no están en el público, pero eso cambiará con el tiempo. Está sangrando. :-) – igrigorik

31

A partir de Sinatra 1.3, también se puede utilizar la nueva API de streaming:

get '/evented' do 
    stream(:keep_open) do |out| 
    EventMachine::PeriodicTimer.new(1) { out << "#{Time.now}\n" } 
    end 
end 
+0

Konstantin - ¿Funciona esto con TODOS los servidores web o simplemente con servidores web como Thin? Tengo problemas para encontrar un código de ejemplo para la nueva API de transmisión que usa un servidor estándar como Passenger ... – wchrisjohnson

+1

Solo con servidores web destacados, como Thin, Rainbows. o Ebb, pero Puma planea apoyar esto. –

+0

La transmisión sin '' keep_open' funciona en todos los servidores, pero no se transmitirá en todos (es decir, no en Webrick). –

Cuestiones relacionadas