服务器消息推送-SSE

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>

测试

  1. 启动项目,打开前端文件
  2. 指定用户发送消息:http://localhost:8080/send?userId=1&msg=测试消息222

image.png