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