1

重複の可能性:
クライアントへの 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 が実行できるようになる前に列挙子を切断するようです。それを埋めます。

いくつかの質問を聞きたいんです:

  1. これはプロキシを実行する正しい方法ですか? 私は最初に従来の Java IO ストリームでこれを行いました。これは正常に機能しましたが、慣用的またはノンブロッキングではありませんでした

  2. これがこの問題を解決するための合理的な方法である場合、Enumerator.close() メソッドはどこに行くべきですか? .onRedeem には .orTimeout と同じ問題があります

ありがとうございました!

4

0 に答える 0