1. 什么是 SSE?
SSE
(Server-Sent Events)是一种允许服务器向客户端推送实时更新的技术。与 WebSocket
不同,SSE
是单向的,即服务器可以向客户端发送数据,但客户端不能向服务器发送数据。SSE 基于 HTTP 协议,使用简单的文本格式进行数据传输。
2. SSE 与 WebSocket 的区别
2.1 通信方式
- SSE: 单向通信,服务器向客户端推送数据。
- WebSocket: 双向通信,服务器和客户端可以互相发送数据。
2.2 协议
- SSE: 基于 HTTP 协议,使用简单的文本格式。
- WebSocket: 基于独立的 WebSocket 协议,支持二进制和文本数据。
2.3 连接管理
- SSE: 客户端通过 HTTP 请求建立连接,服务器保持连接并推送数据。
- WebSocket: 客户端和服务器通过 WebSocket 握手建立连接,之后可以双向通信。
2.4 适用场景
- SSE: 适用于服务器向客户端推送实时更新的场景,如股票行情、新闻推送等。
- WebSocket: 适用于需要双向通信的场景,如聊天应用、在线游戏等。
图解 SSE 和 WebSocket 的区别
+-------------------+ +-------------------+
| | | |
| Client | | Client |
| | | |
+--------+----------+ +--------+----------+
| |
| HTTP Request | WebSocket Handshake
| |
v v
+--------+----------+ +--------+----------+
| | | |
| Server | | Server |
| | | |
+-------------------+ +-------------------+
| |
| SSE (Server Push) | WebSocket (Bi-directional)
| |
v v
+--------+----------+ +--------+----------+
| | | |
| Client | | Client |
| | | |
+-------------------+ +-------------------+
3. SSE 协议格式
SSE 数据格式非常简单,每条消息由若干行文本组成,每行以换行符 \n
结尾。消息可以包含以下字段:
data
: 消息的内容,可以有多行。event
: 事件类型,可选。id
: 消息的唯一标识符,可选。retry
: 客户端重连的时间间隔,单位为毫秒,可选。
图解 SSE 协议格式
event: message\n
id: 123\n
retry: 5000\n
data: {\n
data: "message": "Hello, World!"\n
data: }\n
\n
4. SSE 的使用场景
SSE 适用于以下场景:
- 实时通知: 如新闻推送、系统通知等。
- 实时数据更新: 如股票行情、天气预报等。
- 日志监控: 实时查看服务器日志。
- 进度更新: 如文件上传进度、任务处理进度等。
5. Swoole 实现 SSE 示例
5.1 服务端代码
<?php
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;
$server = new Server("0.0.0.0", 9501);
$server->on("request", function (Request $request, Response $response) {
// 设置响应头
$response->header("Content-Type", "text/event-stream");
$response->header("Cache-Control", "no-cache");
$response->header("Connection", "keep-alive");
// 发送初始数据
$response->write("event: connect\n");
$response->write("data: " . json_encode(["message" => "Connected"]) . "\n\n");
// 模拟实时数据推送
$i = 0;
while (true) {
$i++;
$response->write("data: " . json_encode(["message" => "Message $i"]) . "\n\n");
sleep(1);
}
});
$server->start();
5.2 客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Client</title>
</head>
<body>
<div id="messages"></div>
<script>
const eventSource = new EventSource("http://127.0.0.1:9501");
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
document.getElementById("messages").innerHTML += `<p>${data.message}</p>`;
};
eventSource.onerror = function(event) {
console.error("EventSource failed:", event);
};
</script>
</body>
</html>
6. 总结
SSE 是一种简单且高效的服务器推送技术,适用于需要服务器向客户端实时推送数据的场景。与 WebSocket 相比,SSE 更加轻量级且易于实现。通过 Swoole,我们可以轻松实现 SSE 服务端,并结合前端技术实现实时数据推送功能。