spring boot 整合 sse(server-sent events)

1、简述
sse(server-sent events)是一种基于http协议的单向通信机制,允许服务器向浏览器持续发送实时更新。与websocket不同,sse更简单,使用http/1.1协议即可,不需要额外的协议升级。它通过简单的文本流格式(data: ...\n\n)传输事件,支持自定义事件类型和重连机制。
sse与其他技术的对比
| 技术 | 协议 | 双向通信 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| sse | http | 单向 | 低 | 服务器主动推送(如通知) |
| websocket | ws | 双向 | 高 | 实时聊天、游戏 |
| 长轮询 | http | 半双工 | 中 | 兼容性要求高的场景 |
sse的特点:
- 自动重连:客户端在连接断开时会自动尝试重新连接。
- 轻量级协议:事件流格式简单,无需额外解析库。
- 浏览器原生支持:现代浏览器通过
eventsourceapi直接使用。
2、spring boot 中的sse实现
2.1 添加依赖与配置
验证spring boot版本兼容性:确保使用spring boot 2.2+版本以获得更好的异步支持。
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>3.1.0</version>
</parent>2.2 实现后端接口
代码深度解析:
- 使用
stream.generate生成数据流,但需注意无限流会导致线程阻塞,推荐结合异步线程池。 - 添加事件id和重试机制(增强sse规范支持):
@getmapping(value = "/sse/stream", produces = mediatype.text_event_stream_value)
public flux<string> stream() {
return flux.interval(duration.ofseconds(1))
.map(sequence -> "id: " + sequence + "\n"
+ "data: " + localtime.now() + "\n\n")
.take(10);
}
2.3 超时与异常处理
精细化配置:
- 通过
sseemitter设置超时回调,记录未完成的连接:
emitter.ontimeout(() -> {
log.warn("sse连接超时:{}", emitter);
emitters.remove(emitter);
});
- 全局异常处理:使用
@exceptionhandler捕获ioexception,避免连接中断导致服务不可用。
2.4 前端实现优化
增强健壮性:
- 监听特定事件类型并处理重连:
eventsource.addeventlistener("customevent", function(e) {
console.log("自定义事件数据:", e.data);
});
eventsource.onerror = function() {
settimeout(() => new eventsource('/sse/stream'), 5000); // 5秒后重连
};- 添加心跳检测:服务器定期发送注释行(
:keep-alive\n)防止代理超时。
3、高级实践
3.1 结合spring security实现鉴权
保护sse端点:
@getmapping("/sse/private-stream")
public sseemitter privatestream(authentication authentication) {
if (authentication == null) {
throw new securityexception("未授权访问");
}
return ssepushservice.subscribe();
}
token验证:前端在初始化eventsource时携带token:
new eventsource('/sse/private-stream?token=xxxx');
3.2 分布式场景下的解决方案
使用消息队列广播事件(以redis pub/sub为例):
- 引入依赖:
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-redis</artifactid>
</dependency>- 订阅redis频道并推送消息:
@bean
public messagelisteneradapter redislistener(ssepushservice pushservice) {
return new messagelisteneradapter((message, channel) ->
pushservice.pushmessage(message.tostring()));
}
3.3 性能监控与调优
- 监控连接数:通过
/actuator/metrics/sse.emitters端点(需集成actuator)。 - 背压控制:使用project reactor的
flux处理背压,避免服务器过载。
4、注意事项(增强版)
- 浏览器兼容性:
- ie完全不支持,可通过
polyfill(如eventsource库)降级为长轮询。 - 移动端浏览器需测试网络切换(如4g/wifi)对连接的影响。
- 消息格式规范:
- 每条消息以
data:开头,结尾必须有两个换行符。 - 发送json数据需转义换行符:
data: {\"time\": \"12:00\"}\n\n。
- 每条消息以
- 安全加固:
- 启用https防止中间人攻击。
- 限制每ip连接数,防止ddos攻击。
5、实战案例:实时日志监控系统
架构设计
- 日志收集:filebeat监听日志文件变动。
- 消息中转:kafka接收日志并缓存。
- sse推送:spring boot消费kafka消息并广播。
关键代码
@kafkalistener(topics = "logs")
public void handlelog(string logmessage) {
ssepushservice.pushmessage(logmessage);
}
6、调试与测试技巧
- 使用curl测试sse:
curl -n http://localhost:8080/sse/stream
- 浏览器开发者工具:
- 网络面板查看
eventstream分帧详情。 - 控制台调试
eventsource事件监听。
- 网络面板查看
延伸阅读:
到此这篇关于spring boot 整合 sse(server-sent events)实战案例(全网最全)的文章就介绍到这了,更多相关spring boot 整合 sse内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论