I am trying to implement Server Sent Event push machanism in spring MVC.it is working fine but i am getting exception to in my scenario.

My Requirement: Suppose, In the server side i have created a API which support Server sent event. and i have put timeout for this event infinite. So once, Client will make a call to this API, client will be keep getting new update from serve after some interval of time. till here everything is fine. But problem is occuring when, client is closing the connection(due to close the browser,client lost the internet connection etc). and Server is not aware of it and still try to send the event to the client and getting the error "The response has already been started" and have provided the full exception stack trace down. So Could anyone please help me to handle this scenario without throwing exception at the server side. Thanks!

NOTE: i am using WildFly 10.x

Code Snippet for the Server sent event at the server side:

...
  @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;
    }
...

Exception Stack 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)

0 Answers