Как обработать JSON Stream, выпущенный пружинным чехлом 2 в угловых 5

Spring boot 2 WebFlux генерирует поток Json в новой версии

например

@GetMapping(value = "stream", produces = APPLICATION_STREAM_JSON_VALUE)
public Flux<Data> stream() {
    return Flux.interval(Duration.ofSeconds(1)).map(Data::new);
}

будет производить выдачу новых данных каждую секунду

{"value":"1"}
{"value":"2"}
{"value":"3"}
{"value":"4"}
{"value":"5"}
{"value":"6"}

я пробовал угловой 5 httpclient

findAll(): Observable<Data> {
   return this._http.get<Data>(this.url);
}

но это не работает для меня, так как я хочу быть реактивным, это не отправляет мне результат, так как кеширует результат, пока не прервется соединение

Я хочу спросить, что является лучшим способом справиться с этим Json в угловых 5

5 ответов

Насколько я знаю, до сих пор нет официального решения (19.08.2018), однако я нашел какой-то обходной путь. Каждый метод HttpClient имеет config аргумент, где вы можете передать responseType и другие вещи. Я смешал эти настройки, как показано ниже:

{observe: 'events', responseType: 'text', reportProgress: true}

Тогда вы будете получать события с заданными типами, в диапазоне от 0 до 4. По крайней мере, в моем случае type 3 был интересный контент, который был в поле partialTextно предупреждение - в вашем случае эти сообщения (в partialText поле) будет выглядеть так:

1 сообщение:

{"value":"1"}

2 сообщения:

{"value":"1"}
{"value":"2"}

3 сообщения

{"value":"1"}
{"value":"2"}
{"value":"3"}

итд... итак, мне это удалось как ниже:

method(url, /*if post - body,*/
      {observe: 'events', responseType: 'text', reportProgress: true})
      .pipe(
        filter(e => e.type === 3 && e.partialText),
        map(e => {
          const partials = e.partialText.trim().split('\n');
          return JSON.parse(partials.pop());
        })
      );

С помощью Server-Sent Events это можно сделать так:

import * as EventSource from 'eventsource';
...

const eventSource = new EventSource("http://www.example.com/stream");

eventSource.onmessage = (event) => {
  const data = JSON.parse(event['data']);
}

Это формат NDJson . Мне удалось справиться с этим, сделав следующее:

      let handled = 0
http.get<any>("http://localhost:9000/myapi", {
    observe: "events",
    reportProgress: true,
    responseType: "text" as "json",
}).pipe(
    filter((e: any) => e.type === HttpEventType.DownloadProgress && e.partialText),
    map(e => e.partialText.trim().split("\n"))
).subscribe((arr) => {
    for (let i = handled; i < arr.length; i++) {
        try {
            console.log(JSON.parse(arr[i])) // Do obs.next(obj) here
            handled = i + 1
        } catch (e) { }
    }
})

Вы можете обернуть этот код в Observable и сделатьobs.next(JSON.parse(arr[i]))гдеconsole.logЯ сидел.

Клиент браузера не может использовать поток JSON (application/stream+json), кроме использования отправленных сервером событий или WebSocket.

С требованиями и технологией, которые вы описали, WebSocket лучше подходит.

Что-то, о чем я думаю, может быть, вы могли бы сохранить открытое соединение (процесс получения / выборки) в задаче `` огонь и забыть '', а затем в другом цикле асинхронизации проверьте, есть ли другой контент, а не сохраненный, чтобы сохранить и показать его .

Может быть.

Другие вопросы по тегам