从客户端发送的数据创建枚举器

时间:2012-11-09 09:10:16

标签: scala playframework-2.0

我有一个REST服务(Play Framework 2.0 w / Scala),它通过POST请求接收消息。

我想允许用户查看网页中收到的邮件队列。我想在浏览器和服务器之间创建一个SSE通道,因此服务器会将新消息推送到浏览器。

要创建该SSE流,根据文档,我使用的是Enumerator / Enumeratee / Iteratee链。

我的问题是:如何将从POST请求收到的消息注入枚举器。所以给出如下代码:

def receive(msg: String) = Action {
  sendToEnumerator() 
  Ok
}

val enumerator =  Enumerator.fromCallback( ??? )

def sseStream() = Action {

  Ok.stream(enumerator &> anotherEnumeratee ><> EventStrem()).as("text/evetn-stream")

}

我应该在sendToEnumeratorenumerator(???所在的位置)放置什么。或者我应该只使用WebSockets和Actors? (由于更广泛的兼容性,我赞成SEE,所以如果可能的话,我希望使用SSE)

1 个答案:

答案 0 :(得分:3)

好的,找到了办法:

 // The enum for pushing data to spread to all connected users
  val hubEnum = Enumerator.imperative[String]()

  // The hub used to get multiple output of a common input (the hubEnum)
  val hub = Concurrent.hub[String](hubEnum)

  // Converts message to Json for the web version
  private val asJson: Enumeratee[String, JsValue] = Enumeratee.map[String] {
    text => JsObject(
      List(
        "eventName" -> JsString("eventName"),
        "text" -> JsString(text)
      )
    )
  }

  // loads data into hubEnum
  def receiveData(msg: String) = Action { implicit request =>
    hubEnum push msg
  } 

  // read the Hub iterator and pushes back to clients
  def stream = Action { implicit request =>
     Ok.stream(hub.getPatchCord &> asJson ><> EventSource()).as("text/event-stream")
  }

诀窍是创建一个命令式枚举器。此枚举器允许您在数据可用时将数据推入其中。有了这个,你就可以按照标准程序:基于枚举器创建一个Hub,用一些Enumeratee转换它,然后通过SSE将它发送回浏览器。

感谢this website给我解决方案:)