Question

Dans notre projet, nous utilisons ReactiveMongo avec Play 2.2.1.

Le problème est que pour diffuser des données sous une forme de Enumerator[A], renvoyé par ReactiveMongo est en fait un flux d'objets de valeur, qui ne sont pas séparés par des virgules et n'ont pas d'annotations de début et de fin de flux, qui peuvent être traitées comme des instructions d'ouverture et de fermeture de tableau.

Cela crée un problème pour JSON consommateur JS client, puisque le format attendu est[A1,A2, ...]

Nous avons donc sauté sur des paniers et transformé notre Enumeratee[A] à Enumerator[String], en vérifiant si c'est le premier élément ou non :

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

Cela fonctionne, mais c'est comme inventer la roue.

Existe-t-il une meilleure solution à ce problème courant ?

Était-ce utile?

La solution

Si vous utilisez Comet ou EventSource, vous n'aurez pas à créer manuellement un moyen de générer une sortie et vous pourrez également analyser l'élément de réponse pour l'élément dans le client.Répondre avec un tableau vous obligerait soit à écrire votre propre code d'analyse, soit à attendre que tout soit arrivé côté client avant de pouvoir utiliser l'analyseur JSON build int dans votre JavaScript.

Le streaming avec le protocole EventSource est assez simple en jouant, vous devriez pouvoir faire quelque chose comme :

implicit val cometEncoder = new Comet.CometMessage[JsValue](_.toString)
Ok.chunked(yourEnumerator &> EventSource()).as(EVENT_STREAM)

Et puis dans le HTML du client :

<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>

Il y a un exemple de cela dans les exemples de projets de lecture que vous voudrez peut-être également examiner. $YOUR_PLAY_DIR/samples/scala/eventsource-clock/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top