我正在开发一个 Sinatra 应用程序,它包含一个上传表单,进度条指示上传完成了多少。如ryan dahl所述,该过程如下:
HTTP 上传进度条相当模糊 - 它们通常涉及在服务器上运行的进程,跟踪 HTTP 服务器正在写入的临时文件的大小,然后在客户端每隔几秒钟对服务器进行一次 AJAX 调用。上传以询问上传进度。
每个上传都有一个随机的session-id,并且为了跟踪我class variable在我的应用程序中使用的关联(我知道,这太可怕了——如果你有更好的想法,请告诉我)
configure do
@@assoc = {}
end
我有一条POST上传路线和GET一条用于 AJAX 轮询的路线。在POST路线内,我保存了session-id、Tempfile和 总大小的关联。
post '/files' do
tmp = params[:file][:tempfile]
# from here on, @@assoc[@sid] should have a value, even in other routes
@@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] }
File.open("#{options.filesdir}/#{filename}", 'w+') do |file|
file << tmp.read
end
end
在GET路线中,我根据Tempfile的当前大小计算百分比:
get '/status/:sid' do
h = @@assoc[params[:sid]]
unless h.nil?
percentage = (h[:file].size / h[:size].to_f) * 100
"#{percentage}%"
else
"0%"
end
end
问题是,直到POST请求尚未完成(即,在它读取了所有的 之后Tempfile)才h.nil?返回true,这实际上没有意义,因为我刚刚@@assoc[@sid]在另一条路线中分配了一个值。
那么,我在这里缺少什么?
编辑:我试过
set :reload, falseset :environment, :productionconfig { @@assoc ||= {} }- 我还尝试向它扔一个关系数据库(带有 DataMapper 的 SQLite)
都没有奏效。