Heroku文档的相关信息:
Long-polling and streaming responses
Cedar supports HTTP 1.1 features such as long-polling and streaming responses. An application has an initial 30 second window to respond with a single byte back to the client. However,each byte transmitted thereafter (either received from the client or sent by your application) resets a rolling 55 second window. If no data is sent during the 55 second window,the connection will be terminated.
If you’re sending a streaming response,such as with server-sent events,you’ll need to detect when the client has hung up,and make sure your app server closes the connection promptly. If the server keeps the connection open for 55 seconds without sending any data,you’ll see a request timeout.
这正是我想要做的 – 检测客户端挂起后立即关闭连接.然而,关于Heroku路由层的某些内容似乎阻止了Sinatra通常会检测到流关闭事件.
一些可用于复制此示例的代码:
require 'sinatra/base' class MyApp < Sinatra::Base set :path,'/tmp' set :environment,'production' def initialize @connections = [] EM::next_tick do EM::add_periodic_timer(1) do @connections.each do |out| out << "connections: " << @connections.count << "\n" end puts "*** connections: #{@connections.count}" end end end get '/' do stream(:keep_open) do |out| @connections << out puts "Stream opened from #{request.ip} (now #{@connections.size} open)" out.callback do @connections.delete(out) puts "Stream closed from #{request.ip} (now #{@connections.size} open)" end end end end
我已经使用这个代码说明了这个问题,将示例应用程序添加到了http://obscure-depths-3413.herokuapp.com/.当您连接时,连接数量将增加,但是当您断开连接时,它们永远不会下降. (Gemfile等的演示全部来源于https://gist.github.com/mroth/5853993)
我正在尝试调试这个.任何人知道如何解决它?
附:似乎有一个similar bug in Sinatra,但一年前固定.此问题只发生在Heroku的生产中,但在本地运行时工作正常.
P.S.2.当遍历连接对象时也会发生这种情况,例如添加以下代码:
EM::add_periodic_timer(10) do num_conns = @connections.count @connections.reject!(&:closed?) new_conns = @connections.count diff = num_conns - new_conns puts "Purged #{diff} connections!" if diff > 0 end
在本地工作很好,但连接从来没有像Heroku那样关闭.