1. 什么是 SSE?

SSE(Server-Sent Events)是一种允许服务器向客户端推送实时更新的技术。与 WebSocket 不同,SSE 是单向的,即服务器可以向客户端发送数据,但客户端不能向服务器发送数据。SSE 基于 HTTP 协议,使用简单的文本格式进行数据传输。

2025-02-15T12:45:41.png

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 服务端,并结合前端技术实现实时数据推送功能。