Как вернуть перечислитель JSON из Reactivemongo в Play 2
-
21-12-2019 - |
Вопрос
В нашем проекте мы используем ReactiveMongo
с Play 2.2.1
.
Проблема в том, что для потока данных в виде генеракодицетагкода, возвращаемой Enumerator[A]
, на самом деле является потоком объектов значения, которые не разделены запятыми, и не имеют начала потока и конечных аннотаций, которые могут быть обработаныв качестве раскрытия массива и закрытия.
Это создает проблему для ReactiveMongo
GeneracodicCode, поскольку ожидаемый формат
JSON
Итак, мы прыгнули в обручах и преобразовали наш генеракодицетагкод для JS client
, с проверкой, если это первый элемент, или нет:
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)
)
.
Это работает, но чувствует себя изобретением колеса.
Решение
Если вы используете COMET или Eventsource, вы не должны иметь возможность обрабатывать способ генерировать вывод, и вы также сможете проанализировать элемент ответа для элемента в клиенте.Отвечая на массивом заставит вас либо написать свой собственный анализ кода или подождать, пока все не получится на стороне клиента, прежде чем вы сможете использовать Build int JSON Parser в вашем JavaScript.
Потоковая передача с протоколом Eventionource довольно прост в игре, вы должны иметь возможность сделать что-то вроде:
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>
.
Есть пример этого в образце Play Primasure, которые вы можете посмотреть на $YOUR_PLAY_DIR/samples/scala/eventsource-clock/