马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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、实用场景
- 实时关照:如监控
体系的告警推送。
- 实时更新:如股票行情、体育比分。
- 消息流:如体系日志
、任务进度。
|