ReactiveMongoからのJSONの列挙子をPlay 2で返す方法
-
21-12-2019 - |
質問
私たちのプロジェクトでは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)
)
.
これは機能しますが、ホイールを発明するように感じます。
この一般的な問題のためのより良い解決策はありますか?
解決
あなたが彗星やeventsourceを使うならば、あなたが出力を生成する方法を手にしなければならず、実際にクライアント内のアイテムの応答アイテムを解析することもできます。アレイで回答すると、JavaScriptでBuild Int JSONパーサーを使用する前に、自分の解析コードを作成するか、すべてがクライアント側に到着するまで待機することができます。
ストリーミングEventSourceプロトコルではかなり簡単で、Playによく簡単になり、次のようなことができるはずです。
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/
所属していません StackOverflow