使用SseEmitter不断向网页输出结果

之前写过一篇文章:springmvc不断输出文本到网页,采用的是对response不断进行write和flush实现的。在spring 4.2版本的时候提供了一个SseEmitter可以直接用来实现这个功能。

实例

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

输出实例

data:"hello0"

data:"hello1"

data:"hello2"

data:"hello3"

data:"hello4"

data:"hello5"

//......

注意事项

  • 这里的SseEmitter的send不能阻塞mvc线程,必须提前返回,然后把send放到异步里头 除了使用上述的放入线程池的方式,也可以直接调用标记有async的方法
  • 这里SseEmitter的timeout设置为0,表示不超时. 如果不设置为0,那么如果SseEmitter在指定的时间(AsyncSupportConfigurer设置的timeout,默认为30秒)未完成会抛出异常 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]

小结

SseEmitter在运行比较耗时的任务时非常好用,比如实时查看部署进度,比如查看定时任务的实时输出等。

doc

  • SseEmitter
  • springmvc不断输出文本到网页
  • 实现后台长时间任务的监控
  • 理解Spring MVC中的异步处理请求(下)

原文发布于微信公众号 - 码匠的流水账(geek_luandun)

原文发表时间:2018-01-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java Web

Spring Boot【快速入门】

上面是引自官网的一段话,大概是说: Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来...

5275
来自专栏大内老A

《WCF技术剖析(卷2)》目录

第1章 异常处理 (Exception Handling) 1.1. WCF基本异常处理模式 1.1.1. 当异常从服务端抛出(S101) 1.1.2. 异常细...

2169
来自专栏吴生的专栏

使用 maven 生成一个支持端到端自动测试的 RESTful 服务项目脚手架

和传统后端页面生成技术相较, RESTful 数据服务专注与数据逻辑, 而将数据呈现完全交给前端应用. 这样做可以让后端开发更加单纯, 而且更容易测试. 本文将...

3685
来自专栏coder修行路

让你成功安装vscode中go的相关插件

注意:该演示环境是windows环境,linux和mac环境操作思路一样 vscode中有很多go的相关插件,非常好用如下: gocode gopkgs go-...

3K8
来自专栏JavaNew

Spring Boot实战:Restful API的构建

1865
来自专栏Java进阶架构师

写出我的第一个框架:迷你版Spring MVC

原文:https://www.jianshu.com/p/f454662f497e

2003
来自专栏腾讯云Elasticsearch Service

Elasticsearch Rest Client实战

Elasticsearch官方推荐使用Java REST客户端连接集群并进行数据操作。

6704
来自专栏计算机编程

Jenkins mac上配置原生android

请在gradle中配置好打包的key与alias的值,否则上面的打包方式打出来的包无法安装!

2281
来自专栏老码农专栏

使用 maven 生成一个支持端到端自动测试的 RESTful 服务项目脚手架

2074
来自专栏我的小碗汤

这几个注解的你了解吗

<mvc:annotation-driven />与<context:annotation-config />

1143

扫码关注云+社区

领取腾讯云代金券