アップロード フォームで構成される 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, false
set :environment, :production
config { @@assoc ||= {} }
- また、リレーショナルデータベースを投げてみました(DataMapperを使用したSQLite)
どちらも機能しませんでした。