可能重复:
Play2 Framework proxy streaming content to client keeps connection open after streaming is done
我正在将一个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
谢谢!