Use SseEmitter to continuously output results to web pages.

  spring-mvc

Order

Previously, I wrote an article: springmvc continuously outputs text to web pages, using the implementation of write and flush on response. In Spring version 4.2, a SseEmitter was provided, which can be directly used to implement this function.

Example

@Controller
@RequestMapping("/sse")
public class SseEmitterController {

    private static final Logger LOGGER = LoggerFactory.getLogger(SseEmitterController.class);

    @Autowired
    @Qualifier("mvcTaskExecutor")
    ThreadPoolTaskExecutor mvcTaskExecutor;

    @GetMapping("")
    public SseEmitter sseDemo() throws InterruptedException {
        final SseEmitter emitter = new SseEmitter(0L); //timeout设置为0表示不超时
        mvcTaskExecutor.execute(() -> {
            try {
                for(int i=0;i<100;i++){
                    emitter.send("hello"+i);
                    LOGGER.info("emit:{}","hello"+i);
                    Thread.sleep(1000*1);
                }
                emitter.complete();
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }
}

Output instance

data:"hello0"

data:"hello1"

data:"hello2"

data:"hello3"

data:"hello4"

data:"hello5"

//......

Matters needing attention

  • The send of SseEmitter here cannot block the mvc thread, it must return in advance, and then put send into asynchrony.

In addition to using the above method of putting into the thread pool, you can also directly call the method marked async.

  • Here, SseEmitter’s timeout is set to 0, which means no timeout.

If it is not set to 0, then if SseEmitterTimeout set by AsyncSupportConfigurer, default is 30 seconds) Incomplete throws an exception

org.springframework.web.context.request.async.AsyncRequestTimeoutException: null
    at org.springframework.web.context.request.async.TimeoutDeferredResultProcessingInterceptor.handleTimeout(TimeoutDeferredResultProcessingInterceptor.java:42) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.context.request.async.DeferredResultInterceptorChain.triggerAfterTimeout(DeferredResultInterceptorChain.java:75) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.context.request.async.WebAsyncManager$5.run(WebAsyncManager.java:392) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.onTimeout(StandardServletAsyncWebRequest.java:143) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.apache.catalina.core.AsyncListenerWrapper.fireOnTimeout(AsyncListenerWrapper.java:44) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.AsyncContextImpl.timeout(AsyncContextImpl.java:134) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:153) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:224) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_71]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_71]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_71]

Summary

SseEmitter is very useful when running time-consuming tasks, such as viewing the deployment progress in real time, such as viewing the real-time output of scheduled tasks, etc.

doc