2014-02-26 78 views
5

在我們的項目中,我們使用ReactiveMongoPlay 2.2.1如何從ReactiveMongo返回播放器中的JSON枚舉器2

問題是,以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) 
    ) 

這很有效,但感覺就像發明了輪子。

有沒有更好的解決方案,對於這個常見問題?

+0

不能相信有沒有更好的解決方案:/ – Jean

回答

1

如果您使用彗星或EventSource,則不必手工製作輸出方式,而且實際上也可以解析客戶端中項目的響應項目。使用數組進行響應將迫使您編寫自己的解析代碼,或等到客戶端的所有內容都到達之後才能在JavaScript中使用build int JSON解析器。

與EventSource的協議流傳是玩很容易的,你應該能夠做一些事情,如:

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/