有没有办法将html冲到Sinatra的电线上

时间:2010-06-12 04:05:00

标签: ruby sinatra

我有一个Sinatra应用程序,具有长时间运行的过程(Web刮刀)。我希望应用程序在爬虫运行时而不是在结束时刷新爬虫的进度结果。

我已经考虑过分配请求并使用ajax做一些奇特的东西,但这是一个非常基本的单页面应用程序,它确实需要在发生时将日志输出到浏览器。有什么建议吗?

1 个答案:

答案 0 :(得分:7)

更新(2012-03-21)

从Sinatra 1.3.0开始,您可以使用新的流API:

get '/' do
  stream do |out|
    out << "foo\n"
    sleep 10
    out << "bar\n"
  end
end

旧答案

不幸的是,您没有可以简单地刷新的流(这对于Rack中间件不起作用)。从路径块返回的结果可以简单地响应each。然后,Rack处理程序将使用块调用each,并在该块中将正文的给定部分刷新到客户端。

所有机架响应必须始终响应each并始终将字符串传递给给定块。如果您只是返回一个字符串,Sinatra会为您处理此事。

一个简单的流媒体示例是:

require 'sinatra'

get '/' do
  result = ["this", " takes", " some", " time"]
  class << result
    def each
      super do |str|
        yield str
        sleep 0.3
      end
    end
  end
  result
end

现在,您只需将所有抓取放入each方法:

require 'sinatra'

class Crawler
  def initialize(url)
    @url = url
  end

  def each
    yield "opening url\n"
    result = open @url
    yield "seaching for foo\n"
    if result.include? "foo"
      yield "found it\n"
    else
      yield "not there, sorry\n"
    end
  end
end

get '/' do
  Crawler.new 'http://mysite'
end