2015-01-06 42 views
0

我需要为我的Play 2.3应用程序添加一个WebSocket-to-TCP代理,但在使用Akka I/O的传出TCP连接支持背压时,我没有看到任何WebSocket。有明确的基于角色的API中没有支持,但James Roper saysDo Play WebSockets支持背压吗?

Iteratees通过设计解决这个问题,你养活不了一个新元素到 iteratee直到去年将来它返回已被赎回,因为你 在那之前没有提及它。

但是,我没有看到他指的是什么。在示例中使用的Iteratee.foreach似乎太简单了。我在iteratee API中看到的唯一期货是用于完成计算的结果。我应该为每条消息完成一个Future[Unit]还是什么?

回答

4

Iteratee.foldM让我们沿着每一步传递一个状态,就像正常的折叠操作一样,并返回一个未来。如果你没有这样的状态,你只能通过Unit,它会表现为一个foreach,在未来完成之前不会接受下一步。

这里是一个效用函数正是这么做的一个例子:

def foreachM[E](f: E => Future[Unit])(implicit ec: ExecutionContext): Iteratee[E, Unit] = 
    Iteratee.foldM[E, Unit](Unit)((_, e) => f(e)) 
2

IterateeIterator不一样。一个Iteratee确实支持背压(实际上你会发现自己有相反的问题 - 默认情况下他们不会做任何缓冲(至少在管道内 - 当然异步套接字仍然有接收缓冲区),所以你有时必须向枚举器/迭代器管道添加显式缓冲步骤以获得合理的性能)。这些例子看起来很简单,但这仅仅意味着框架正在做一个框架,让事情变得简单。如果您在处理程序中执行大量工作或进行异步调用,则不应使用简单的Iteratee.foreach,而应使用接受基于Future的处理程序的API;如果你阻止Iteratee之间,那么你会阻止整个事情,浪费你的线程,并打败使用它们。

+0

“Iteratee是不一样的迭代器” - 这是一个错字。编辑。 – Derecho

+0

“使用接受基于Future的处理程序的API” - 是否有一个?你能给个例子吗? – Derecho

+0

您可以通过在每一步(使用明确的“Cont”而不是'Iteratee.foreach')并使用'Iteratee.flatten'返回一个'Future [Iteratee []]'手动执行“。我不太清楚play API是否有更好的变体(我习惯scalaz iteratees),但是,如果需要,你可以编写一个。 – lmm