Play2 iteratee и enumerator потоковая передача большого файла не удалась
Возможный дубликат:
Play2 Framework прокси потокового контента на клиенте сохраняет соединение открытым после завершения потоковой передачи
Я передаю файл размером 11 Мб с веб-службы клиенту. По сути, это сквозной прокси. вот мой код:
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 МБ, я могу получить только 2 МБ до того, как методы.close() убьют поток.
Я ЗНАЮ, что Итератор получает все данные (я вижу это, когда я распечатываю их), но, похоже, что вызов.close() на Перечислителе выполняется слишком рано и отключает перечислитель до того, как получатель сможет заполнить его.
У меня есть несколько вопросов:
это правильный способ сделать прокси? Сначала я сделал это с традиционными потоками ввода-вывода Java, которые работали нормально, но не были идиоматичными или неблокирующими
Если это разумный способ решить эту проблему, куда должен идти метод Enumerator.close()? .onRedeem имеет ту же проблему, что и.orTimeout
Спасибо!