Подтвердить что ты не робот

Потоковые данные из приложения Sinatra/Rack

Я пытаюсь передать текстовые данные (XML/JSON) из приложения Rack (1,1.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, и если да, то как я могу использовать его в своем приложении?

4b9b3361

Ответ 1

Ни Вебрик, ни Тонкая поддержка не течет именно так. Вы могли бы попробовать Монгреля или Единорога. Если вы хотите использовать 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 для потоковой передачи: здесь является патчем.

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

Вам обязательно нужно взглянуть на стойку веб-сервер Goliath. Он поддерживает потоковое вещание. Я использую его для потокового api файла firehose.

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