ruby – HTTP流连接(SSE)客户端断开未检测到Sinatra / Thin在Heroku

前端之家收集整理的这篇文章主要介绍了ruby – HTTP流连接(SSE)客户端断开未检测到Sinatra / Thin在Heroku前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在雪松堆栈上部署一个Sinatra流SSE响应应用程序.不幸的是,当它在开发中完美地工作时,一旦部署到Heroku,调用连接时,回调或errback就不会被调用,导致连接池充满了陈旧的连接(从来没有超时,因为数据仍然被发送给他们服务器端.)

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那样关闭.

解决方法

更新:直接与Heroku路由团队(谁是好人!)完成工作后,现在已经在其新的路由层中修复,并且应该在任何平台上正常工作.

猜你在找的Ruby相关文章