我正在尝试建立遵循以下步骤的方案:
Init
上创建了Flux
发布者Init
上)订户subscribe
BUFFER_SIZE
个事件基于http://projectreactor.io/docs/core/release/reference/#advanced-parallelizing-parralelflux和https://www.baeldung.com/reactor-core,我正在尝试使用create
和publish
来执行此操作,而我遇到的问题是调用的线程flux.connect
被困在发布者内部的while循环中。
以下是使用spring-boot-starter-webflux
的最小工作示例:
private ConnectableFlux<Integer> flux;
private Scheduler scheduler;
private int nextRead = 0;
private static final int BUFFERSIZE = 100;
private List<Integer> sink = new LinkedList<Integer>() ;
@PostConstruct
public void Init() {
this.scheduler = Schedulers.newSingle("Streamer");
flux = Flux.<Integer>create(fluxSink -> {
while (true) {
fluxSink.next(nextRead++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).publishOn(scheduler).publish();
}
@GetMapping("/subscribe")
public void subscribe(){
this.flux.subscribeOn(scheduler,false).subscribe(new CoreSubscriber<Integer>() {
@Override
public Context currentContext() {
return null;
}
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(Long.MAX_VALUE);
}
@Override
public void onNext(Integer e) {
while (sink.size() >= BUFFERSIZE) sink.remove(0);
sink.add(e);
logger.debug("sink event: " + e);
}
@Override
public void onError(Throwable t) {}
@Override
public void onComplete() {}
});
}
@GetMapping("/start")
public void startStream(){
logger.debug("EventStreamSimulator startStream before connect");
this.flux.connect();
logger.debug("EventStreamSimulator startStream after connect");
}
@GetMapping("/values")
public Flux<Integer> getEvents(){
return Flux.fromIterable(sink);
}
基于此代码,/start
上的Web请求将开始流式传输,但是http
线程将陷入发射器无限循环中。 /values
上的请求和日志记录表明它运行正常(但是原来的http request
至/start
从未完成/返回)
示例日志:
2018-10-09 18:12:54.798调试6024 --- [ctor-http-nio-2] com.example.FluxPocController:emmit事件:0
2018-10-09 18:12:54.798调试6024 --- [Streamer-1] com.example.FluxPocController:下沉事件:0
然后,这是一个问题:使用publishOn
的这些异步方式是否支持Flux.create
指令?如果可以,怎么使用?