重複の可能性:
クライアントへの Play2 フレームワーク プロキシ ストリーミング コンテンツは、ストリーミングが完了した後も接続を開いたままにします
Web サービスからクライアントに 11 MB のファイルをストリーミングしています。これは基本的にパススルー プロキシです。ここに私のコードがあります:
def getStreamEnumerator(streamUrl: String, mimeType: String) = {
Akka.future {
val dataContent = Enumerator.imperative[Array[Byte]]()
WS.url(streamUrl).withHeaders("Accept"->mimeType).get { response =>
Iteratee.fold[Array[Byte], PushEnumerator[Array[Byte]]](dataContent)({
(pipe, bytes) => {
println(bytes.length)
pipe.push(bytes)
pipe
}
})
}.orTimeout("Oops", 20000L).map {eitherPromiseOrTimeout =>
println(eitherPromiseOrTimeout)
dataContent.close()
}
dataContent
}
}
そして私はそれを呼びます:
getStreamEnumerator(imageUrl, "image/png").map { e =>
Ok.stream(e).withHeaders(
"Content-Type"->"image/png",
"Connection"->"Close"
)
}
遅いサービスの場合、これはうまく機能し、ファイル全体を取得します。高速なサービスの場合、ファイルのごく一部 (サイズは異なります) のみを取得し、残りの画像は切り取ります。画像がたとえば 11 MB の場合、.close() メソッドがストリームを強制終了する前に 2 MB しか取得できません。
Iteratee がすべてのデータを取得することは知っていますが (印刷すると表示されます)、Enumerator の .close() 呼び出しの実行が早すぎて、interatee が実行できるようになる前に列挙子を切断するようです。それを埋めます。
いくつかの質問を聞きたいんです:
これはプロキシを実行する正しい方法ですか? 私は最初に従来の Java IO ストリームでこれを行いました。これは正常に機能しましたが、慣用的またはノンブロッキングではありませんでした
これがこの問題を解決するための合理的な方法である場合、Enumerator.close() メソッドはどこに行くべきですか? .onRedeem には .orTimeout と同じ問題があります
ありがとうございました!