2021-11-01 16:40:02 +08:00
|
|
|
|
---
|
|
|
|
|
title: SSE
|
|
|
|
|
description: 服务端事件
|
|
|
|
|
published: true
|
2021-11-01 16:40:23 +08:00
|
|
|
|
date: 2021-11-01T08:40:22.257Z
|
2021-11-01 16:40:02 +08:00
|
|
|
|
tags: wg-basic
|
|
|
|
|
editor: markdown
|
|
|
|
|
dateCreated: 2021-11-01T08:40:00.487Z
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# 对比WebSocket
|
|
|
|
|
|
|
|
|
|
WebSocet是双通道的,即可以向服务器发送数据,也可以接收服务器数据
|
|
|
|
|
ServerSendEvent是单通道的,只能接收服务器数据(服务器主动推送)
|
|
|
|
|
|
|
|
|
|
# Controller
|
|
|
|
|
|
|
|
|
|
方式1:
|
|
|
|
|
利用前端页面的重连机制,sse页面会自动重连(类似ajax的定时连接,意义不大)
|
|
|
|
|
```java
|
|
|
|
|
@RequestMapping(value = "sse", produces = "text/event-stream;charset=UTF-8")
|
|
|
|
|
@ResponseBody
|
|
|
|
|
public String push() {
|
|
|
|
|
return "data:message\n\n";
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
方式2:
|
|
|
|
|
服务端主动推送,这里用循环模拟了业务处理
|
|
|
|
|
```java
|
|
|
|
|
@RequestMapping(value = "sse")
|
|
|
|
|
@ResponseBody
|
|
|
|
|
public void push(HttpServletRequest request, HttpServletResponse response) {
|
|
|
|
|
response.setContentType("text/event-stream");
|
|
|
|
|
response.setCharacterEncoding(ISystemConstant.CHARSET_UTF8);
|
|
|
|
|
try {
|
|
|
|
|
PrintWriter writer = response.getWriter();
|
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
|
Thread.sleep(1000);
|
|
|
|
|
writer.write("data:index:" + i + "\n\n");
|
|
|
|
|
writer.flush();
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException | IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# 页面
|
2021-11-01 16:40:23 +08:00
|
|
|
|
|
|
|
|
|
> IE不支持EventSource,可以使用WebSocket代替
|
|
|
|
|
{.is-warning}
|
|
|
|
|
|
2021-11-01 16:40:02 +08:00
|
|
|
|
```javascript
|
|
|
|
|
// 判断是否支持
|
|
|
|
|
if ('EventSource' in window) {
|
|
|
|
|
var source = new EventSource(top.restAjax.path('route/teamtype/sse', []));
|
|
|
|
|
source.addEventListener('message', function(e) {
|
|
|
|
|
console.log(e.data);
|
|
|
|
|
});
|
|
|
|
|
source.addEventListener('open', function(e) {
|
|
|
|
|
console.log('open');
|
|
|
|
|
}, false);
|
|
|
|
|
// 响应finish事件,主动关闭EventSource
|
|
|
|
|
source.addEventListener('finish', function(e) {
|
|
|
|
|
console.log('finish');
|
|
|
|
|
source.close();
|
|
|
|
|
}, false);
|
|
|
|
|
// 异常
|
|
|
|
|
source.addEventListener('error', function(e) {
|
|
|
|
|
console.log('error', e);
|
|
|
|
|
if (e.readyState == EventSource.CLOSED) {
|
|
|
|
|
console.log("连接关闭");
|
|
|
|
|
}
|
|
|
|
|
}, false);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|