我想在数据块进入我的 Rails 服务器时将远程数据(视频)流式传输到客户端,使我的 Rails 服务器充当反向代理。 在 Ruby 3.2.2 上使用 Rails 7.0.4
我已经用
ActionController::Live
构建了一些“有效”的东西,但它首先读取远程文件/流的所有块,因此如果文件很大,客户端会等待很长时间。根据 docs,它能够在写入数据时将数据流式传输到客户端,但它会在写入之前先读取所有数据。我从每 1000 个块的调试输出中看到这一点,它在客户端获取任何数据之前就填满了。我如何为客户提供传入块的服务?
这是代码,在传递给客户端之前首先从远程源读取所有块:
class SocketController < ApplicationController
include ActionController::Live
def test
uri = URI('https://somefile')
i = 0
response.headers['Content-Type'] = 'video/mp4'
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri
http.request request do |remote_response|
remote_response.read_body do |chunk|
i += 1
puts i if i % 1000 == 0
response.stream.write chunk
end
end
end
ensure
response.stream.close
end
end
谢谢!
Rack 2.2 破坏了
ActionController::Live
的流媒体功能,根据 https://github.com/rack/rack/issues/1619
更新到 Rails 7.1 with Rack 3 修复了这个问题。
对于 Rack 2.2.x,在控制器方法
中添加
response.headers["Last-Modified"] = Time.now.httpdate
或 在 config.middleware.delete Rack::ETag
中添加 application.rb
会有所帮助。
来源:https://github.com/rack/rack/issues/1619#issuecomment-848460528
有时在 stackoverflow 上提问,就像问你的宠物一样,你得到一个想法,搜索一下,它就会起作用:-)