Play2 iteratee和大文件的枚举器流失败

时间:2012-10-02 18:08:10

标签: scala streaming playframework-2.0 enumerator iterate

  

可能重复:
  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之前切断了枚举器能够填补它。

我有几个问题:

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

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

  3. 具有相同的问题

    谢谢!

0 个答案:

没有答案