SSE(Server Sent Event):服务器发送事件,客户端发起请求后,连接会一直保持,等待服务器发送数据,它与 WebSocket 的明显区别就是 SSE 是半双工的,只能服务端向客户端发送数据,优点是不需要其他的类库,开发难度较低,默认支持断线重连
依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @CrossOrigin @RestController public class SSEController {
private static final Map<Integer, SseEmitter> sseCache = new ConcurrentHashMap<>();
@GetMapping("/subscribe") public SseEmitter subscribe(Integer userId) { SseEmitter sseEmitter = new SseEmitter(5 * 60 * 1000L); sseCache.put(userId, sseEmitter); sseEmitter.onTimeout(() -> sseCache.remove(userId)); sseEmitter.onCompletion(() -> System.out.println("完成")); return sseEmitter; }
@GetMapping("/send") public void send(Integer userId, String msg) throws IOException { SseEmitter sseEmitter = sseCache.get(userId); if (sseEmitter != null) { sseEmitter.send(msg); } }
@GetMapping("/over") public void over(Integer userId) { SseEmitter sseEmitter = sseCache.get(userId); if (sseEmitter != null) { sseEmitter.complete(); sseCache.remove(userId); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>sse测试</title> <script> const source = new EventSource('http://localhost:8080/subscribe?userId=1'); source.onmessage = function (event) { let log = document.getElementById('log'); log.innerHTML = "onMessage:" + event.data + "<br>" + log.innerHTML; }; source.onopen = function (event) { console.log(event); let log = document.getElementById('log'); log.innerHTML = "开启回调"; }; </script> </head> <body> <div id="log"></div> </body> </html>
|
测试
- 启动项目,打开前端文件
- 指定用户发送消息:http://localhost:8080/send?userId=1&msg=测试消息222