Согласно документации 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 ниже:
Headers">
Вкладка EventStream - пуста:
EventStream"> Timing">
Сравните это с заголовками веб-сайта, например http://www.emojitracker.com/:
Headers">
Если на вкладке EventStream события отображаются правильно:
EventStream">
Важным является тот факт, что при использовании конечной точки Spring с WebClient
Я могу успешно получить каждое событие в ожидаемое время, используя .bodyToFlux
. Таким образом, похоже, что в событиях отсутствует какая-либо форма конфигурации, которую Chrome ожидает от потока событий, отправляемых сервером, - но какой?