使用服务器发送事件时,春季“对异步状态为[MUST_DISPATCH]的请求,调用[asyncError()]无效”

时间:2019-08-26 15:05:29

标签: java spring spring-boot reactive-programming server-sent-events

我有一个Spring Boot应用程序,它使用服务器发送的事件将数据流式传输到基于React的前端(React客户端使用EventSource,从后端获取数据并使用实时数据绘制图形),以及当我启动时一段时间后,多个并行流(例如,我开始在浏览器中的多个不同并行选项卡中开始实时绘图)流(有时只是其中的一些)暂停并且不会暂停,直到我用实时流刷新所有选项卡。

当流刷新时,我会收到多个类似这样的异常:

java.lang.IllegalStateException: Calling [asyncError()] is not valid for a request with Async state [MUST_DISPATCH]
    at org.apache.coyote.AsyncStateMachine.asyncError(AsyncStateMachine.java:440) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:512) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.coyote.Request.action(Request.java:430) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:401) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:239) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
    at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]

我发现this topic on SO,但是使用Jetty容器并没有帮助,并且在尝试@EnableAdminServer方法时,我在应用程序启动后立即得到了以下提示:

java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:157)
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:98)
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:64)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:347)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139)
    at com.my.MyApplication.main(MyApplication.java:17)

我应该怎么做才能使流并行工作而不会出现问题? 有关如何流式传输数据的示例:

@GetMapping(value = "/endpoint/", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux getLastData(@PathVariable("cabinNumber") String cabinNumber) {
        return Flux.interval(Duration.ofMillis(1000))
                .map(interval -> someRepository.find());
    }

0 个答案:

没有答案