10

アップロード フォームで構成される Sinatra アプリを開発しています。進行状況バーには、アップロードがどれだけ完了したかが示されます。ryan dahlによって説明されているプロセスは次のとおりです。

HTTP アップロードのプログレス バーはかなり難読化されています。通常、HTTP サーバーが書き込んでいる一時ファイルのサイズを追跡するサーバー上で実行されているプロセスが含まれます。その後、クライアント側では、サーバーに対して数秒ごとに AJAX 呼び出しが行われます。アップロードの進行状況を尋ねるアップロード。

すべてのアップロードにはランダムなsession-idがあり、アプリで採用している関連付けを追跡するために使用しclass variableています (これは恐ろしいことです。より良いアイデアがあれば教えてください)。

configure do
  @@assoc = {}
end

POSTアップロード用のルートと、GETAJAX ポーリング用のルートがあります。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)

どちらも機能しませんでした。

4

2 に答える 2

4

問題が何であるかがわかったと思います:

tmp = params[:file][:tempfile]ファイルが完全に受信されるまで戻りません。

于 2010-06-22T22:50:08.623 に答える
1
@@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] }

する必要があります

@@assoc[params[:sid]] = { :file => tmp, :size => env['CONTENT_LENGTH'] }
于 2010-06-22T18:37:17.303 に答える