Я пытаюсь реализовать механизм отправки событий, отправленных с сервера, весной MVC.it работает нормально, но в моем сценарии я получаю исключение.
Мои требования: Предположим, на стороне сервера я создал API, который поддерживает отправленное сервером событие. и я поставил тайм-аут для этого
событие бесконечное. Поэтому, как только Клиент выполнит вызов этого API, через некоторое время клиент продолжит получать новое обновление от сервера.
времени. пока здесь все в порядке. Но проблема возникает, когда клиент закрывает соединение (из-за закрытия браузера, клиент потерял интернет-соединение и т. Д.). и сервер не знает об этом и все еще пытается отправить событие клиенту и
получить сообщение об ошибке «Ответ уже запущен» и предоставил полную трассировку стека исключений. Так может кто-нибудь, пожалуйста, помогите мне справиться с этим сценарием без исключения на стороне сервера. Спасибо!
ПРИМЕЧАНИЕ: я использую WildFly 10.x
Фрагмент кода для отправленного сервером события на стороне сервера:
...
@GetMapping("/streamssemvc")
public SseEmitter streamSseMvc() {
System.out.println("server sent event resource called:");
SseEmitter emitter = new SseEmitter(0L); // 0 or < 0 means this see timeout will for infinite time. else it's value is in millisecond
ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor();
sseMvcExecutor.execute(() -> {
try {
for (int i = 0; true; i++) {
SseEventBuilder event = SseEmitter.event()
.data("push coutner:- " + b++)
.id(String.valueOf(i))
.name("sse event");
emitter.send(event);
Thread.sleep(1000);
}
} catch (Exception ex) {
emitter.completeWithError(ex);
}
});
return emitter;
}
...
Strace для стека исключений:
15:44:27,242 ERROR [io.undertow.request] (default task-3) UT005071: Undertow request failed HttpServerExchange{ GET /munsiji-service/rest/myapp/streamssemvc request {Connection=[keep-alive], Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3], Accept-Language=[en-US,en;q=0.9], Accept-Encoding=[gzip, deflate, br], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36], Upgrade-Insecure-Requests=[1], Host=[localhost:8080]} response {Connection=[keep-alive], X-Powered-By=[Undertow/1], Server=[WildFly/10], Transfer-Encoding=[chunked], Content-Type=[text/event-stream;charset=UTF-8], Date=[Sun, 12 May 2019 10:12:31 GMT]}}: java.lang.IllegalStateException: UT000002: The response has already been started
at io.undertow.server.HttpServerExchange.setStatusCode(HttpServerExchange.java:1370)
at io.undertow.servlet.spec.AsyncContextImpl.handleError(AsyncContextImpl.java:404)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:306)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:209)
at io.undertow.servlet.spec.AsyncContextImpl$2$1.handleRequest(AsyncContextImpl.java:188)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.servlet.spec.AsyncContextImpl$2.run(AsyncContextImpl.java:185)
at io.undertow.servlet.spec.AsyncContextImpl$6.run(AsyncContextImpl.java:455)
at io.undertow.servlet.spec.AsyncContextImpl$TaskDispatchRunnable.run(AsyncContextImpl.java:566)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)