문제

우리 프로젝트에서 우리는 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)
   )

이것은 효과가 있지만 바퀴를 발명하는 것처럼 느껴집니다.

이 일반적인 문제에 대한 더 나은 해결책이 있습니까?

도움이 되었습니까?

해결책

Comet 또는 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/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top