问题描述
我正在尝试从 Ruby (1.9.1p378) Sinatra (1.0) Rack (1.2.1) 应用程序流式传输文本数据 (XML/JSON).建议的解决方案(例如 是否有将 html 刷新到 Sinatra 中的电线的方法)似乎不起作用 - 当我产生一些无限流的元素(例如从 %w(foo bar).cycle
).我尝试将 webrick
和 thin
作为服务器.
I am trying to stream textual data (XML/JSON) from a Ruby (1.9.1p378) Sinatra (1.0) Rack (1.2.1) application. The suggested solutions (e.g. Is there a way to flush html to the wire in Sinatra) do not seem to work - the server just blocks when I yield elements of some infinite stream (e.g. from %w(foo bar).cycle
). I tried webrick
and thin
as servers.
有什么关于完成这项工作的建议吗?我应该使用 http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html 如果是这样,我将如何在我的应用程序中使用它?
Any suggestions on getting this done? Should I use http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html and if so how would I use it in my application?
推荐答案
Webrick 和 Thin 都不支持这种方式的流式传输.你可以试试 Mongrel 或 Unicorn.如果要使用 Thin 或 Rainbows!,则必须挂钩到事件循环中才能实现流式传输:
Neither Webrick nor Thin support streaming that way. You could try Mongrel or Unicorn. If you want to use Thin or Rainbows!, you have to hook into the event loop in order to achieve 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
我最近以这种方式编写了一个 EventSource 实现:
I recently wrote a EventSource implementation that way:
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 进行流式传输:这里是一个补丁.
If you want to use Webrick for Streaming: here is a patch.
这篇关于从 Sinatra/Rack 应用程序流式传输数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!