有没有办法将 html 刷新到 Sinatra 中的线路

发布于 2024-09-05 18:15:23 字数 156 浏览 2 评论 0原文

我有一个 Sinatra 应用程序,其进程运行时间较长(网络抓取工具)。我希望应用程序在爬网程序运行时而不是在结束时刷新爬网程序进度的结果。

我考虑过分叉请求并使用 ajax 做一些奇特的事情,但这是一个非常基本的单页应用程序,实际上只需要在发生时将日志输出到浏览器。有什么建议吗?

I have a Sinatra app with a long running process (a web scraper). I'd like the app flush the results of the crawler's progress as the crawler is running instead of at the end.

I've considered forking the request and doing something fancy with ajax but this is a really basic one-pager app that really just needs to output a log to a browser as it's happening. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

给不了的爱 2024-09-12 18:15:23

更新 (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

Update (2012-03-21)

As of Sinatra 1.3.0, you can use the new streaming API:

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

Old Answer

Unfortunately you don't have a stream you can simply flush to (that would not work with Rack middleware). The result returned from a route block can simply respond to each. The Rack handler will then call each with a block and in that block flush the given part of the body to the client.

All rack responses have to always respond to each and always hand strings to the given block. Sinatra takes care of this for you, if you just return a string.

A simple streaming example would be:

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

Now you could simply place all your crawling in the each method:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文