Потоковая передача данных из приложения Sinatra / Rack - PullRequest
22 голосов
/ 08 сентября 2010

Я пытаюсь транслировать текстовые данные (XML / JSON) из приложения Ruby (1.9.1p378) Sinatra (1.0) Rack (1.2.1). Предлагаемые решения (например, Есть ли способ сбросить html на провод в Sinatra ), похоже, не работают - сервер просто блокирует, когда я выдаю элементы некоторого бесконечного потока (например, из %w(foo bar).cycle). Я пробовал webrick и thin в качестве серверов.

Любые предложения по выполнению этого? Должен ли я использовать http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html, и если да, то как мне использовать его в моем приложении?

Ответы [ 4 ]

31 голосов
/ 03 октября 2011

Начиная с Sinatra 1.3, вы также можете использовать новый потоковый API:

get '/evented' do
  stream(:keep_open) do |out|
    EventMachine::PeriodicTimer.new(1) { out << "#{Time.now}\n" }
  end
end
19 голосов
/ 10 сентября 2010

Ни Webrick, ни Thin не поддерживают потоковую передачу таким образом.Вы можете попробовать дворнягу или единорога.Если вы хотите использовать Thin или Rainbows !, вам нужно подключиться к циклу событий, чтобы добиться потоковой передачи:

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

Я недавно написал реализацию EventSource следующим образом:

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

Если вы хотите использовать Webrick для потоковой передачи: здесь - это патч.

7 голосов
/ 07 апреля 2011

Как упоминал Колин, Голиаф может передавать как ответные данные, так и входящие (большие загрузки файлов). В репозитории есть пример для потоковой передачи данных клиенту: https://github.com/postrank-labs/goliath/blob/master/examples/stream.rb

Вместо таймера вы можете легко подключить любой другой поток данных для передачи данных клиенту. Например, вы можете подключить очередь AMQP или любую другую очередь сообщений непосредственно к Голиафу и позволить ей выступать в качестве интерфейса HTTP для этих данных.

5 голосов
/ 05 апреля 2011

Обязательно посмотрите на стоечный веб-сервер Голиафа .Он поддерживает потоковую передачу из коробки.Я использую его для потокового API в стиле firehose.

Goliath - это и сервер приложений, и облегченная платформа, предназначенная для решения следующих задач: полностью асинхронная обработка, поддержка промежуточного программного обеспечения, простая настройка, высокая производительностьи, пожалуй, самое главное, читаемый и поддерживаемый код.

...