在以下示例中,我希望端点直接发出Server Sent Events
,或至少在1-2秒后发出。
但是实际上,首先汇总所有1000页,然后发出事件。
@GetMapping(value = "/test", produces = TEXT_EVENT_STREAM_VALUE)
public Flux<JSONObject> test(Integer pages) {
int pages = 1000; //for showcase
return Flux.range(0, pages)
.map(pageNumber -> Arrays.asList(1 * pageNumber, 2 * pageNumber, 3 * pageNumber))
.flatMap(numbers -> Mono.zip(a(numbers), b(numbers)))
.map(tuple -> {
JSONObject json = new JSONObject();
json.put("test", tuple);
return json;
});
}
问题:每个页面完成后,我需要更改什么以获得即时事件?
有趣的是,如果我删除.flatMap(zip...)
行并在最后的.map()
方法内添加一个sleep命令,则我将每100ms直接接收一个事件:
Flux.range(0, pages)
.map(pageNumber -> Arrays.asList(1 * pageNumber, 2 * pageNumber, 3 * pageNumber))
.map(tuple -> {
TimeUnit.MILLISECONDS.sleep(100); //direct events each 100ms
JSONObject json = new JSONObject();
json.put("test", tuple);
return json;
});
所以这是我想要的结果,但是现在如何向其中添加一个并行运行多个子方法的非阻塞zip并汇总结果(我认为这是zip的目的)?
旁注:我知道这个例子本身没有任何意义,只是为了说明我的问题,即在每页之后都无法直接获取SSE。
对于此问题的目标,压缩方法无关紧要,但是要完整:
private Mono<String> a() {
return Mono.fromCallable(() -> {
TimeUnit.MILLISECONDS.sleep(100); //simulate slow service
return "a";
});
}
private Mono<String> b() {
return Mono.fromCallable(() -> "b");
}
答案 0 :(得分:1)
我怀疑您需要链接Mono.zip
才能使其正常工作。
@GetMapping(value = "/test", produces = TEXT_EVENT_STREAM_VALUE)
public Flux<JSONObject> test(Integer pages) {
int pages = 1000;
return Flux.range(0, pages)
.map(pageNumber -> Arrays.asList(1 * pageNumber, 2 * pageNumber, 3 * pageNumber))
.flatMap(numbers -> {
return Mono.zip(a(numbers), b(numbers))).map(tuple -> {
JSONObject json = new JSONObject();
json.put("test", tuple);
return json;
});
}
答案 1 :(得分:0)
我必须添加一个.range().subscribeOn(Schedulers.elastic())
,至少在使用它时可以使用。虽然我不知道为什么。