简体   繁体   English

从Sinatra / Rack应用程序流式传输数据

[英]Streaming data from Sinatra/Rack application

I am trying to stream textual data (XML/JSON) from a Ruby (1.9.1p378) Sinatra (1.0) Rack (1.2.1) application. 我试图从Ruby(1.9.1p378)Sinatra(1.0)Rack(1.2.1)应用程序流文本数据(XML / JSON)。 The suggested solutions (eg 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 (eg from %w(foo bar).cycle ). 建议的解决方案(例如, 有没有办法将html刷新到Sinatra中的线路 )似乎不起作用 - 当我产生一些无限流的元素时(例如来自%w(foo bar).cycle ), %w(foo bar).cycle I tried webrick and thin as servers. 我试过webrickthin作为服务器。

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? 我应该使用http://sinatra.rubyforge.org/api/classes/Sinatra/Streaming.html ,如果是这样,我将如何在我的应用程序中使用它?

Starting with Sinatra 1.3, you could also use the new streaming API: 从Sinatra 1.3开始,您还可以使用新的流API:

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

Neither Webrick nor Thin support streaming that way. Webrick和Thin都不支持流式传输。 You could try Mongrel or Unicorn. 你可以试试Mongrel或Unicorn。 If you want to use Thin or Rainbows!, you have to hook into the event loop in order to achieve streaming: 如果你想使用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

I recently wrote a EventSource implementation that way: 我最近写了一个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

If you want to use Webrick for Streaming: here is a patch. 如果你想使用Webrick for Streaming: 是一个补丁。

As Colin mentioned, Goliath can stream response data, as well as incoming (large file uploads). 正如Colin所说,Goliath可以传输响应数据以及传入(大文件上传)。 There is an example in the repo for streaming data to the client: https://github.com/postrank-labs/goliath/blob/master/examples/stream.rb 回购中有一个例子,用于将数据流传输到客户端: https//github.com/postrank-labs/goliath/blob/master/examples/stream.rb

Instead of a timer, you can easily hook up any other data stream to push data to the client. 您可以轻松连接任何其他数据流以将数据推送到客户端,而不是计时器。 For example, you can connect an AMQP queue, or any other message queue directly to Goliath and let it act as an HTTP frontend to that data. 例如,您可以将AMQP队列或任何其他消息队列直接连接到Goliath,并让它充当该数据的HTTP前端。

You should definitely take a look at the rack-able Goliath web server . 你一定要看看机架式Goliath网络服务器 It supports streaming out-of-the-box. 它支持开箱即用的流媒体。 I am using it for a firehose style streaming api. 我用它来做一个firehose风格的流式api。

Goliath is both an app server and a lightweight framework designed to meet the following goals: fully asynchronous processing, middleware support, simple configuration, high-performance, and arguably most importantly, readable and maintainable code. Goliath既是app服务器又是轻量级框架,旨在满足以下目标:完全异步处理,中间件支持,简单配置,高性能,可以说是最重要的可读和可维护代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM