Отладка отправленных сервером событий из Spring - PullRequest
2 голосов
/ 30 сентября 2019

Согласно документации Spring , при возврате Flux Spring должен отправлять отправленное сервером событие для каждого элемента, возвращаемого подпиской.

Вот примерный контроллер REST:

package myapp.controller;

import myapp.MyOutput;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/api/v1/test")
@Api(tags = "Test API")
public class TestController {

    @ApiOperation(
        value = "Test",
        response = MyOutput.class,
        produces = MediaType.TEXT_EVENT_STREAM_VALUE
    )
    @RequestMapping(
        value = "",
        method = RequestMethod.PATCH,
        produces = MediaType.TEXT_EVENT_STREAM_VALUE
    )
    @ApiResponses(
        value = {
            @ApiResponse(code = 200, message = "Service execution successful"),
            @ApiResponse(code = 400, message = "Bad input data"),
            @ApiResponse(code = 500, message = "An internal server error occurred."),
            @ApiResponse(code = 503, message = "The service is not available.")
        }
    )
    public ResponseEntity<Flux<MyOutput>> test() {
        return ResponseEntity.ok().header("Connection", "Keep-Alive")
            .body(Flux.range(0, 1000)
                .delayElements(Duration.ofSeconds(1))
                .map(MyOutput::new)
            );
    }
}

Пример ответа с использованием wget:

data:{"recordCount":0}

data:{"recordCount":148}

data:{"recordCount":226}

data:{"recordCount":266}

data:{"recordCount":272}

data:{"recordCount":286}

data:{"recordCount":287}

data:{"recordCount":293}

data:{"recordCount":294}

При отладке конечной точки с использованием Chrome или Postman клиенты, похоже, интерпретируют события как части фрагментированного ответа, а не какпоток событий. Я подтвердил, что данные ответа совпадают и требуют ожидаемого количества времени. См. Снимки экрана с вкладки Chrome Network ниже:

image Headers">

Вкладка EventStream - пуста:

image EventStream"> image Timing">


Сравните это с заголовками веб-сайта, например http://www.emojitracker.com/:

image Headers">

Если на вкладке EventStream события отображаются правильно:

image EventStream">


Важным является тот факт, что при использовании конечной точки Spring с WebClientЯ могу успешно получить каждое событие в ожидаемое время, используя .bodyToFlux. Таким образом, похоже, что в событиях отсутствует какая-либо форма конфигурации, которую Chrome ожидает от потока событий, отправляемых сервером, - но какой?

...