在我们的项目中,我们将ReactiveMongo
与Play 2.2.1
一起使用。
问题是,由Enumerator[A]
返回的ReactiveMongo
形式的数据流实际上是一个值对象流,它们没有用逗号分隔,并且没有流开头并结束注释,可以将其视为数组开始和结束语句。
这会为JSON
消费者JS client
带来问题,因为预期的格式是。{
[A1,A2, ...]
所以我们跳入了箍,并将我们的Enumeratee[A]
转换为Enumerator[String]
,并检查它是否是第一个元素:
var first:Boolean = true
val aToStrs = (as.map(a => {
if(first) {
first = false;
Json.stringify(Json.toJson(a))
} else {
"," + Json.stringify(Json.toJson(a))
}
}))
Ok.chunked(
Enumerator.enumInput(Input.El("[")) andThen
aToStrs andThen
Enumerator.enumInput(Input.El("]")) andThen
Enumerator.enumInput(Input.EOF)
)
这很有效,但感觉就像在发明轮子一样。
对于这个常见问题,是否有更好的解决方案?
答案 0 :(得分:1)
如果你使用comet或EventSource,你不必手工制作输出的方法,你也可以实际解析客户端中项目的响应项。响应数组会强制您编写自己的解析代码,或者等到所有内容都到达客户端,然后才能在JavaScript中使用build int JSON解析器。
使用EventSource协议进行流式传输非常简单,您应该可以执行以下操作:
implicit val cometEncoder = new Comet.CometMessage[JsValue](_.toString)
Ok.chunked(yourEnumerator &> EventSource()).as(EVENT_STREAM)
然后在客户端html:
<script type="text/javascript">
var es = new EventSource(jsRouter.controllers.Application.streamIt().url)
es.addEventListener("message", function (event) {
var item = JSON.parse(event.data)
// ... do something with the json value ...
})
</script>
您可能还希望查看的播放示例项目中有一个示例$YOUR_PLAY_DIR/samples/scala/eventsource-clock/