我正在将一个 11mb 的文件从 Web 服务流式传输到客户端。这本质上是一个直通代理。这是我的代码:
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"
)
}
对于慢速服务,这很好用,我得到了整个文件。对于快速服务,我只得到文件的一小部分(大小不同,顺便说一句),其余的图像被切断。如果图像是 11mb,在 .close() 方法终止流之前,我可能只会得到 2mb。
我知道 Iteratee 获取了所有数据(我在打印出来时看到了它),但是,似乎 Enumerator 上的 .close() 调用运行得太快了,并且在 interatee 能够之前切断了枚举器填补;填写(表格,资料。
我有几个问题:
这是做代理的正确方法吗?我首先用传统的 Java IO 流来做这个,它工作正常,但不是惯用的或非阻塞的
如果这是解决此问题的合理方法,那么 Enumerator.close() 方法应该去哪里?.onRedeem 与 .orTimeout 有同样的问题
谢谢!