Как обработать исключение, когда Сервер (Wildfly) обрабатывает ответ, и в этот момент Клиент отключается или недоступен? - PullRequest
0 голосов
/ 12 мая 2019

Я пытаюсь реализовать механизм отправки событий, отправленных с сервера, весной 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)
...