基本概念
服务器发送事件(Server-Sent Events)是一种用于从服务器到客户端的 单向、实时传输技术,基于HTTP协议实现。
它有几个重要的特点:
- 单向通信:SSE只支持服务器向客户端的单向通信,客户端不能向服务器发送数据。
- 文本格式:SSE使用纯文本格式传输数据,使用HTTP响应 text/event-stream MIME 类型。
- 保持连接:SSE通过保持一个持久的HTTP连接,实现服务器向客户端推送更新,而不需要客户端频繁轮询。
- 自动重连:如果连接中断,浏览器会自动尝试重新连接,确保数据流的连续性。
SSE数据格式
SSE数据流的格式非常简单,每个事件使用data字段,事件以两个换行符结束。还可以使用id字段来标识事件,并且retry字段可以设置重新连接的时间间隔。
示例格式如下:
data: First message\n
\n
data: Second message\n
\n
data: Third message\n
id: 3\n
\n
retry: 10000\n
data: Fourth message\n
\n
自主实现SSE
实现SSE非常简单,无论是Java服务端还是前端HTML5都支持了SSE,以下内容仅作了解。
1)服务器端
需要生成符合SSE格式的响应,并设置合适的HTTP头。使用Servlet来实现SSE示例:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/sse")
public class SseServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
for (int i = 0; i < 10; i++) {
writer.write("data: Message " + i + "\n\n");
writer.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writer.close();
}
}
当然,如果是在Spring项目中,还有更简单的实现方式,直接给请求返回SseEmitter对象即可。
注意,一定要使用Get请求!!
示例代码:
@GetMapping("/sse")
public SseEmitter testSSE() {
// 建立 SSE 连接对象,0 表示不超时
SseEmitter emitter = new SseEmitter(0L);
... 业务逻辑处理
return emitter;
}
2)Web前端
可以使用JavaScript的EventSource对象来使用连接和处理服务器发送的事件。
示例代码:
// 创建 SSE 请求
const eventSource = new EventSource(
"http://localhost:8080/sse"
);
// 接收消息
eventSource.onmessage = function (event) {
console.log(event.data);
};
// 生成结束,关闭连接
eventSource.onerror = function (event) {
if (event.eventPhase === EventSource.CLOSED) {
eventSource.close();
}
};
应用场景
由于现代浏览器普遍支持SSE,所以它的应用场景非常广泛,AI对话就是SSE的一个典型的应用场景。
再举一些例子:
- 实时更新:股票价格、体育比赛比分、新闻更新等需要实时推送的应用
- 日志监控:实时监控服务器日志或应用状态
- 通知系统:向客户端推送系统通知或消息