ruby PUMA Web服务器保持缓冲响应,并在调用response.stream.close时发送它

lnvxswe2  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(80)

我正在尝试以设定的时间间隔将数据写入流。

class StreamController < ApplicationController
  include ActionController::Live

  def stream
    response.headers['Content-Type'] = 'text/event-stream'
    5.times do
      response.stream.write "data: hello world\n\n"
      sleep 1
    end
  ensure
    response.stream.close
  end
end

但是当我向/stream端点发送get请求(使用curl)时,我得到:“data:hello world\n\n”在5秒后一次全部出现5次,而不是接收“data:Hello World\n\n”。我使用的是rails 7.0.4自带的默认puma网络服务器。我的猜测是,它缓冲响应,然后在调用response. stream. close时发送它。
我尝试将options = { flush_headers: true }添加到puma配置文件中,但没有帮助。

vojdkbi0

vojdkbi01#

rackpuma已经解决了这个问题并修复了很长时间的bug。官方上,你需要rack v3puma v6,但是rails 7不支持rack v3。
据我所知,最后一个hickup是Rack::ETag中间件,您可以删除config.middleware.delete Rack::ETag。但你可能需要它,所以现在有一个解决方案:

class StreamController < ApplicationController
  include ActionController::Live

  def stream
    response.headers["Content-Type"] = "text/event-stream"

    # this bypasses etag calculation and magic happens
    response.headers["Last-Modified"] = Time.now.httpdate

    5.times {
      response.stream.write "hello world\n"
      sleep 1
    }
  ensure
    response.stream.close
  end
end

如果你看到ETag: W/"53827b3eddcd709c853e748ffd5314fb",你就错了:

$ curl -i http://localhost:3000/stream/stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
Last-Modified: Tue, 22 Aug 2023 10:29:34 GMT
Cache-Control: no-cache
X-Request-Id: 3dbb7f14-e167-4b5c-9cea-27c4ec131f24
X-Runtime: 0.094270
Server-Timing: start_processing.action_controller;dur=0.16
Transfer-Encoding: chunked

hello world
hello world
hello world
hello world
hello world
  • 你不能告诉,但它是流:)* puma v6.3.1rack v2.2.7

https://github.com/rack/rack/issues/1619

相关问题