1、简述
sse(server-sent events)是一种基于http协议的单向通信机制,允许服务器向浏览器持续发送实时更新。与websocket不同,sse更简单,使用http/1.1协议即可,不需要额外的协议升级。
sse的特点:
- 单向通信:服务器推送数据给客户端,客户端无法向服务器发送消息。
- 简单易用:基于http协议,无需复杂的配置。
- 浏览器支持:现代浏览器大多内置支持(如chrome、edge、firefox等)。
2、spring boot 中的sse实现
2.1 添加依赖
sse无需额外的依赖,spring boot自带对sse的支持。创建一个spring boot项目即可。
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency>
2.2 实现后端接口
使用mediatype.text_event_stream_value
作为返回类型即可开启sse。以下代码是一个简单的实现。
package com.example.sse.controller; import org.springframework.http.mediatype; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.restcontroller; import java.time.localtime; import java.util.concurrent.executors; import java.util.concurrent.timeunit; import java.util.stream.stream; @restcontroller public class ssecontroller { @getmapping(value = "/sse/stream", produces = mediatype.text_event_stream_value) public stream<string> stream() { // 模拟数据流 return stream.generate(() -> "当前时间:" + localtime.now()) .limit(10); // 限制10条消息 } }
2.3 配置超时时间(可选)
默认情况下,spring boot的响应会超时。可以在application.properties
中调整超时时间:
server.servlet.session.timeout=30s spring.mvc.async.request-timeout=30000
2.4 前端实现
sse在前端通过eventsource
对象实现。以下是一个简单的前端示例:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>sse example</title> </head> <body> <h1>实时消息</h1> <div id="messages"></div> <script> const eventsource = new eventsource('/sse/stream'); eventsource.onmessage = function(event) { const messagesdiv = document.getelementbyid('messages'); const newmessage = document.createelement('p'); newmessage.textcontent = event.data; messagesdiv.appendchild(newmessage); }; eventsource.onerror = function() { console.error('sse连接出错,正在尝试重连...'); eventsource.close(); }; </script> </body> </html>
3、高级实践
使用spring scheduler推送数据,在实际场景中,可能需要定时向客户端推送数据。例如,监控系统定时更新。
package com.example.sse.service; import org.springframework.http.mediatype; import org.springframework.stereotype.service; import org.springframework.web.servlet.mvc.method.annotation.sseemitter; import java.io.ioexception; import java.util.concurrent.copyonwritearraylist; @service public class ssepushservice { private final copyonwritearraylist<sseemitter> emitters = new copyonwritearraylist<>(); public sseemitter subscribe() { sseemitter emitter = new sseemitter(30_000l); emitters.add(emitter); emitter.oncompletion(() -> emitters.remove(emitter)); emitter.ontimeout(() -> emitters.remove(emitter)); return emitter; } public void pushmessage(string message) { for (sseemitter emitter : emitters) { try { emitter.send(message, mediatype.text_plain); } catch (ioexception e) { emitters.remove(emitter); } } } }
创建一个控制器订阅和推送消息:
package com.example.sse.controller; import com.example.sse.service.ssepushservice; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.restcontroller; @restcontroller public class ssepushcontroller { private final ssepushservice ssepushservice; public ssepushcontroller(ssepushservice ssepushservice) { this.ssepushservice = ssepushservice; } @getmapping("/sse/subscribe") public sseemitter subscribe() { return ssepushservice.subscribe(); } @getmapping("/sse/push") public void pushmessage() { ssepushservice.pushmessage("当前时间:" + system.currenttimemillis()); } }
注意事项:
- 浏览器兼容性:sse不支持ie,但现代浏览器支持良好。
- 连接断开处理:可通过
eventsource
的onerror
事件重新连接。 - 性能问题:对大量订阅者时,需考虑使用分布式消息队列优化(如kafka)。
- 超时时间:默认30秒超时,需要根据实际需求调整。
4、适用场景
- 实时通知:如监控系统的告警推送。
- 实时更新:如股票行情、体育比分。
- 消息流:如系统日志、任务进度。
到此这篇关于spring boot 整合 sse(server-sent events)的文章就介绍到这了,更多相关spring boot 整合 sse内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论