Karp 的技术博客

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

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2025年02月15日 12:46
0

目录

来自 《SSE 协议详解:使用场景与 Swoole 实现》