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