我有一个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")
}
我应该在sendToEnumerator
和enumerator
(???所在的位置)放置什么。或者我应该只使用WebSockets和Actors? (由于更广泛的兼容性,我赞成SEE,所以如果可能的话,我希望使用SSE)
答案 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给我解决方案:)