【问题标题】:Do Play WebSockets support back-pressure?Play WebSockets 是否支持背压?
【发布时间】:2015-01-21 04:38:44
【问题描述】:

我需要在我的 Play 2.3 应用程序中添加一个 WebSocket-to-TCP 代理,但是虽然使用 Akka I/O 的传出 TCP 连接支持背压,但我看不到 WebSocket 的任何内容。基于actor的API显然不支持,但是James Roper says

Iteratees 通过设计来处理这个问题,您不能将新元素输入到 iteratee until last future 它返回已被赎回,因为你 在那之前不要引用它。

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

【问题讨论】:

    标签: scala playframework websocket backpressure


    【解决方案1】:

    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阻塞,那么你阻塞了整个事情,浪费了你的线程,并完全失去了使用它们的意义。

      【讨论】:

      • “Iteratee 与 Iterator 不同”——这是一个错字。已编辑。
      • “使用接受基于 Future 的处理程序的 API”——有吗?能举个例子吗?
      • 您可以通过在每一步返回Future[Iteratee[...]](使用显式Cont 而不是Iteratee.foreach)并使用Iteratee.flatten 来“手动”完成。我不太了解 play API,不知道是否有更好的变体(我习惯于 scalaz iteratees),但见鬼,如果需要,您可以编写一个。
      • Iteratee.foldM 允许将状态传递给每个步骤,就像常规折叠操作一样,并返回一个未来。如果您没有这样的状态,您可以只传递 Unit ,它将表现为一个 foreach ,在未来完成之前不会接受下一步。
      • @johanandren 我现在正在工作。如果你把它作为答案,我会接受它。
      猜你喜欢
      • 2019-06-05
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      相关资源
      最近更新 更多