我有一个Sinatra应用程序,它有一个长时间运行的进程(一个web刮板)。我希望应用程序在爬虫运行时刷新爬虫进度的结果,而不是在爬虫结束时。
我曾考虑过使用ajax分叉请求并做一些花哨的事情,但这是一个非常基本的单页应用程序,它只需要在发生时将日志输出到浏览器即可。有什么建议吗?
发布于 2010-06-12 17:27:17
更新(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
。然后,机架处理程序将使用一个块调用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
https://stackoverflow.com/questions/3027435
复制相似问题