news 2026/3/13 3:17:45

SpringBoot + ResponseBodyEmitter 实时异步流式推送

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot + ResponseBodyEmitter 实时异步流式推送

目前市面上异步推送大多用的是websocket或者http轮训,今天咱们换一种更为简便的方式来实现流式输出,那就是ResponseBodyEmitter

其实,ResponseBodyEmitter并非新技术,早在 Spring Framework 4.2 版本就已被引入。直到最近,我们在开发一个滚动日志输出功能时,才深入了解到它的强大之处。

ResponseBodyEmitter 的作用

相较于 websocket 技术,ResponseBodyEmitter更加简单易用。它主要用于处理异步的 HTTP 响应,其核心优势在于允许逐步将数据发送到客户端,而非一次性发送所有内容。这一特性使得它在需要长时间处理或进行流式传输的场景中表现出色。需要注意的是,ResponseBodyEmitter本质上是一个接口。

使用场景

  1. 长轮询:服务器在有数据时会立即响应客户端请求,若暂无数据,则保持连接开放,等待数据到来。
  2. 服务器推送事件 (SSE):服务器能够持续不断地向客户端推送各类事件,实现实时交互。
  3. 流式传输:可逐步发送大量数据,像文件下载或者实时数据流传输等场景都适用。
  4. 异步处理:在处理耗时任务时,能逐步返回处理结果,避免客户端长时间等待,提升用户体验。

业务场景举例

在实际业务中,ResponseBodyEmitter有着广泛的应用,比如进度条的实时更新、实时聊天功能、股票价格的实时更新、系统日志的流式输出以及 AI 的流式响应等。

实时日志流实战

接下来,我们通过一个简单的实时日志流功能,来深入了解ResponseBodyEmitter的使用。假设我们有一个应用程序,需要实时查看服务器的日志,以便快速定位和解决问题。

创建控制器

首先,我们在 Spring Boot 应用中创建一个控制器,借助ResponseBodyEmitter实现实时日志流。

import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; @RestController @RequestMapping("/api/log") publicclass LogController { @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public ResponseBodyEmitter streamLogs() { ResponseBodyEmitter emitter = new ResponseBodyEmitter(); // 开启异步线程处理数据并发送 new Thread(() -> { try { while (true) { String logEntry = getLatestLogEntry(); if (logEntry != null) { emitter.send(logEntry); } // 每秒检查一次日志更新 Thread.sleep(1000); } } catch (Exception e) { // 出现异常时结束响应并传递错误信息 emitter.completeWithError(e); } }).start(); return emitter; } private String getLatestLogEntry() { // 模拟从日志文件中获取最新日志条目 return"2025-02-12 12:00:00 - INFO: User logged in successfully."; } }

运行效果

当我们启动这个应用程序,并访问/api/log/stream路径时,就能看到一个实时更新的日志流。服务器会每秒向客户端推送一条新的日志条目,客户端会将其显示在页面上,效果如下:

ResponseBodyEmitter 的核心方法

  • send(Object data):向客户端发送数据,该方法可以多次调用,实现数据的逐步发送。
  • complete():用于结束响应流,表示数据已经全部发送完毕。
  • onTimeout(Runnable callback):设置超时回调函数,当连接超时时,会执行该回调。
  • onCompletion(Runnable callback):设置完成回调函数,当数据发送完成后,会执行该回调。

ResponseBodyEmitter 工作原理

异步数据生成与推送

在传统的 HTTP 请求 - 响应模式中,服务器通常需要等待整个响应数据生成完成后,才会将其一次性发送给客户端。而ResponseBodyEmitter打破了这种模式,它允许服务端在任务执行过程中异步地生成响应数据。

当有部分数据准备好时,就可以立即调用send()方法将这些数据推送给客户端,而无需等待整个任务完成。这就好比一场接力赛,每完成一段赛程(生成一部分数据),就马上将接力棒(数据)传递给客户端,大大提高了数据传输的实时性。

分块传输机制

ResponseBodyEmitter采用了 HTTP 的分块编码(Chunked Encoding)方式来传输数据。在传统的 HTTP 响应中,通常需要在响应头中明确指定Content-Length,表示整个响应数据的长度。但在分块传输中,服务器不会提前设置Content-Length,而是将数据分成多个独立的块,每个块都有自己的长度标识。

客户端在接收到数据块后,可以立即对其进行处理,而不必等待整个响应数据接收完毕。这种方式使得数据可以边生成边传输,减少了客户端的等待时间,提高了用户体验。

连接生命周期管理

为了确保资源的合理使用,ResponseBodyEmitter提供了对连接生命周期的有效管理。当所有数据都发送完毕后,需要调用complete()方法来明确告知客户端响应结束,关闭连接。如果在数据传输过程中出现异常,可以调用completeWithError()方法,结束响应并向客户端传递错误信息。

这样可以避免连接长时间保持开放,造成资源浪费。

注意事项

  1. 客户端支持:虽然大多数浏览器和 HTTP 客户端库都支持分块传输,但某些老旧的客户端可能存在兼容性问题。
  2. 超时设置:为避免长连接长时间占用资源,可以为ResponseBodyEmitter设置超时时间,示例代码如下:
emitter.onTimeout(() -> emitter.complete());
  1. 线程安全ResponseBodyEmittersend()方法是线程安全的,但在使用时需要注意控制任务线程的生命周期,避免出现资源泄漏。
  2. 连接关闭:务必确保在任务结束时调用complete()completeWithError()方法,否则可能导致连接无法正常关闭,造成资源浪费。

小结

ResponseBodyEmitter是 Spring 框架提供的轻量级流式传输解决方案,它能够显著提升高并发和实时性场景下的用户体验。通过ResponseBodyEmitter,我们可以轻松实现服务器向客户端的实时数据推送。

无论是进度条的实时更新、实时聊天、股票价格的实时监控还是系统日志的流式输出,ResponseBodyEmitter都能帮助我们构建更加动态和互动的应用程序。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/10 17:12:20

大模型落地全攻略:从技术实践到商业价值创造

大模型技术正从实验室快速走向产业应用,成为企业数字化转型的核心驱动力。据IDC预测,到2026年,60%的企业将把大模型技术嵌入核心业务流程,实现运营效率提升30%以上。本文系统梳理大模型落地的四大关键路径——微调技术、提示词工程…

作者头像 李华
网站建设 2026/3/11 21:11:30

项目分享|Wan2.2:开源且进阶的大规模视频生成模型

引言 随着AIGC技术的快速发展,视频生成成为多模态生成领域的核心方向之一。但现有模型往往面临生成效率低、画质差、运动表现力不足等问题,难以兼顾工业级应用的效率与学术研究的可扩展性。Wan2.2的推出,正是为了解决这些痛点——它以创新的…

作者头像 李华
网站建设 2026/2/24 7:19:34

探索基于LCL的APF双闭环控制:卓越谐波治理之路

基于LCL的APF双闭环控制,电流环采用重复控制PI,电压环采用PI,THD值在3%以下,电压在700V。 只是一种控制方法一种谐波检测算法在电力系统的谐波治理领域,基于LCL的有源电力滤波器(APF)双闭环控制…

作者头像 李华
网站建设 2026/3/9 7:56:35

【会员】2015–2030年我国100米分辨率按年龄与性别分组的人口栅格数据

人口的动态变化已成为影响社会经济发展、资源分配以及生态环境的重要因素。精准掌握人口的时空分布特征,对于制定可持续发展政策、优化城市规划以及应对社会经济挑战具有重要意义。之前我们分享过来自于WorldPop平台的2015-2030年我国100米分辨率人口总数栅格数据和…

作者头像 李华
网站建设 2026/3/11 20:35:57

程序员外包的价值重塑与科学决策:2026企业技术资源整合新视角

在数字化进程不断深化的今天,技术能力已成为企业的核心驱动力。然而,自建并维持一支完整、高效的技术团队,往往意味着高昂的固定成本与漫长的组建周期。在此背景下,程序员外包作为一种成熟的技术资源整合模式,正被越来…

作者头像 李华