1

可能重复:
Play2 Framework 代理向客户端流式传输内容在流式传输完成后保持连接打开

我正在将一个 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 能够之前切断了枚举器填补;填写(表格,资料。

我有几个问题:

  1. 这是做代理的正确方法吗?我首先用传统的 Java IO 流来做这个,它工作正常,但不是惯用的或非阻塞的

  2. 如果这是解决此问题的合理方法,那么 Enumerator.close() 方法应该去哪里?.onRedeem 与 .orTimeout 有同样的问题

谢谢!

4

0 回答 0