【问题标题】:How to stop a background thread in Sinatra once the connection is closed连接关闭后如何在 Sinatra 中停止后台线程
【发布时间】:2011-10-03 00:10:13
【问题描述】:

我正在尝试通过 Sinatra 使用 twitter 流 API,并在用户搜索关键字时为他们提供实时更新。

require 'sinatra'
require 'eventmachine'
require 'em-http'
require 'json'

STREAMING_URL = 'https://stream.twitter.com/1/statuses/sample.json'

get '/' do
  stream(:keep_open) do |out|
    http = EM::HttpRequest.new(STREAMING_URL).get :head => { 'Authorization' => [ 'USERNAME', 'PASS' ] }
    buffer = ""
    http.stream do |chunk|
      puts "still chugging"
      buffer += chunk
      while line = buffer.slice!(/.+\r?\n/)
        tweet = JSON.parse(line)
        unless tweet.length == 0 or tweet['user'].nil?
            out << "<p><b>#{tweet['user']['screen_name']}</b>: #{tweet['text']}</p>" 
        end
      end
    end
  end
end

如果用户关闭连接,我希望 em-http-request 流的处理停止。有人知道怎么做吗?

【问题讨论】:

    标签: ruby sinatra eventmachine


    【解决方案1】:

    Eric 的回答很接近,但它的作用是在您的 twitter 流关闭后关闭响应正文(不是客户端连接,顺便说一句),这通常不会发生。这应该有效:

    require 'sinatra/streaming' # gem install sinatra-contrib
    # ...
    
    get '/' do
      stream(:keep_open) do |out|
        # ...
        out.callback { http.conn.close_connection }
        out.errback { http.conn.close_connection }
      end
    end
    

    【讨论】:

    • 我刚刚为 Sinatra 添加了多回调支持,因此在下一个 Sinatra 版本中,此示例将不再需要 sinatra-contrib。
    • 该回调确实有效,但 em-http-request 不响应关闭或取消绑定(例如 http.close)。有什么想法吗?
    【解决方案2】:

    我对 Sinatra 流 API 还不是很熟悉,但是您尝试过吗?

    http.callback { out.close }

    【讨论】: