我有一个Sinatra应用程序,具有长时间运行的过程(Web刮刀)。我希望应用程序在爬虫运行时而不是在结束时刷新爬虫的进度结果。
我已经考虑过分配请求并使用ajax做一些奇特的东西,但这是一个非常基本的单页面应用程序,它确实需要在发生时将日志输出到浏览器。有什么建议吗?
答案 0 :(得分:7)
从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