Pergunta

Em nosso projeto estamos usando ReactiveMongo com Play 2.2.1.

O problema é que o fluxo de dados em uma forma de Enumerator[A], retornado por ReactiveMongo é na verdade um fluxo de objetos de valor, que não são separados por vírgulas e não possuem anotações de início e fim de fluxo, que podem ser tratadas como instruções de abertura e fechamento de array.

Isto cria um problema para JSON consumidor JS client, já que o formato esperado é[A1,A2, ...]

Então saltámos e transformamos a nossa Enumeratee[A] para Enumerator[String], verificando se é o primeiro elemento ou não:

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

Isso funciona, mas parece que inventamos a roda.

Existe uma solução melhor para este problema comum?

Foi útil?

Solução

Se você usar Comet ou EventSource, não precisará criar manualmente uma maneira de gerar saída e também poderá analisar o item de resposta por item no cliente.Responder com uma matriz forçaria você a escrever seu próprio código de análise ou esperar até que tudo chegasse ao lado do cliente antes de poder usar o analisador build int JSON em seu JavaScript.

Streaming com o protocolo EventSource é muito fácil de jogar, você deve ser capaz de fazer algo como:

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

E então no html do cliente:

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

Há um exemplo disso nos projetos de amostra da peça que você também pode querer ver $YOUR_PLAY_DIR/samples/scala/eventsource-clock/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top