2

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

我想让用户查看网页中收到的消息队列。我想在浏览器和服务器之间创建一个 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)

4

1 回答 1

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")
  }

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

感谢这个网站给我解决方案:)

于 2012-11-09T19:33:28.633 回答