我希望用户能够点击“下载”链接并在生成文件时下载文件。同样,即使在文件生成完成之前,下载也会立即开始。当我从curl请求时,下面的代码似乎会流式传输,但是在通过firefox或chrome请求启动下载之前等待整个代完成:
class Streamer
def each
1200.times do |i|
yield i.to_s + "\n"
sleep 0.1
end
yield "END\n"
end
end
class StaticPagesController < ApplicationController
def stream
headers["Content-Type"] = "text/plain"
headers["Content-disposition"] = "attachment; filename=\"test.txt\""
headers['X-Accel-Buffering'] = 'no'
headers["Cache-Control"] ||= "no-cache"
#headers["Transfer-Encoding"] = "chunked"
headers.delete("Content-Length")
self.response.status = 200
self.response_body = Streamer.new
end
end
取消注释传输编码会中断curl的流式传输。我正在跑步:
bundle exec unicorn_rails --config-file unicorn.config.rb
和unicorn.config.rb是:
listen 3000, tcp_nopush: false, :tcp_nodelay => true
答案 0 :(得分:0)
我知道这是一个古老的问题,但是如果对某人有用,我将放弃我会遵循的方法。
也许您可以使用后台作业,并创建一个模型,该模型将存储该区域文件以及一些功能信息,例如查找该文件的方式及其当前启动项。
class GeneratedFile < ActiveRecord
# fields :status, :file_name, :streamed_content, :mime_type, :generation_message
enum status: %i[processing ready error]
validates :status, presence: true
end
class StaticPagesController
def stream
generating_file = GeneratedFile.create! do |file|
file.processing!
end
# Supposing that this class exist and launches a background job
BackgroundJob.execute_later(file: generating_file)
end
end
然后,在执行后台作业期间,您可以修改记录的内容及其状态。
答案 1 :(得分:0)
您发布的示例代码可在Rack 2.1.x上使用,但由于this change in Rack::ETag及其标识流响应的原因,将不再在Rack 2.2.x中流式传输。
在将response_body设置为(鸭型)Enumerable时,您现在需要添加此标头(以防止Rack :: ETag预处理整个Enumerable来构建摘要):
headers["Last-Modified"] = Time.current.httpdate