Pregunta

En nuestro proyecto estamos usando ReactiveMongo con Play 2.2.1.

El problema es que transmitir datos en forma de Enumerator[A], devuelto por ReactiveMongo es en realidad una secuencia de objetos de valor, que no están separados por comas y no tienen anotaciones de inicio y fin de secuencia, que pueden tratarse como declaraciones de apertura y cierre de matriz.

Esto crea un problema para JSON consumidor JS client, ya que el formato esperado es[A1,A2, ...]

Así que nos lanzamos al aro y transformamos nuestra Enumeratee[A] a Enumerator[String], comprobando si es el primer elemento o no:

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

Esto funciona, pero parece como inventar la rueda.

¿Existe una solución mejor para este problema común?

¿Fue útil?

Solución

Si usa Comet o EventCource, no tendrá que hacer una forma de manualización a mano para generar salida y también podrá analizar el elemento de respuesta para el artículo en el cliente.Respondiendo con una matriz le obligaría a escribir su propio código de análisis o esperar hasta que todo haya llegado al lado del cliente antes de poder usar el analizador de compilación INT JSON en su JavaScript.

Streaming con el protocolo de EventCource es bastante fácil con el juego, debería poder hacer algo como:

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

y luego en el cliente 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>

Hay un ejemplo de esto en los proyectos de muestra de juego que es posible que desee ver también $YOUR_PLAY_DIR/samples/scala/eventsource-clock/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top