2

我想在 Play 中编写一个应用程序!framework 2.2.x 作为异步方法和play.api.libs.iterattee包的练习。我想要做的是获取一个 POST 请求,其中包含一个大文件上传,并将其逐块发送,作为单独请求的下载。

“Play for Scala”一书和这个例子Iteratee引导我接收请求中的文件,我可以在我在 custom 中定义的任何块中累积或迭代BodyParser。在提供分块响应时,我需要为Enumerator响应提供一个 - 就像Ok.chunked(enumerator)Enumerator 提供新块时它将提供给客户端一样。

现在我想把它们放在一起,我似乎找不到一种优雅的反应方式来将新数据块从上传客户端异步传播到下载。似乎没有一种好方法可以将Iteratee(在本例中BodyParser)接收到的数据“转发”到新的Enumerator(在本例中为响应提供输出的)。

我想出了两种方法,但它们对我来说似乎都不够好:

  • 用于在我的 BodyParserplay.api.libs.iteratee.Concurrent.boradcast中生成一个Channel和一个,并将每个收到的块推送到. 没有 s 所具有的属性- Enumerator 不会产生新值,直到应用它消耗旧值。如果我这样做,如果上传者的互联网连接比下载者更快,我就会“膨胀” ,占用越来越多的内存,而不是一次处理一个块。EnumeratorChannelChannelsEnumeratorIterateeChannel

  • 创建一个代理 akkaActor并将上传的文件逐块发送给它,仅在下载器使用完最后一个文件后才发送下一个文件。但是在这种情况下,每个块被发送到下载器的确认必须通过Actor代理,以便上传Iteratee器将另一个块发送到代理。这对我来说似乎是不必要的开销。

我想我的问题是双重的:

  1. 有没有一种简单的方法来构造一个“转发”Enumerator来生成一个接收到的值Iteratee
  2. 在我的用例中,使用 Play 和 Scala 的异步工具包实现我想到的场景的正确方法是什么?
4

1 回答 1

2

您可以使用Concurrent.joined

val (iteratee, enumerator) = Concurrent.joined[Array[Byte]]
于 2014-05-05T23:37:38.567 回答