【PHP】快速掌握:SSE vs WebSocket 选型 + PHP实战SSE

小破孩
2026-03-27 / 0 评论 / 1 阅读 / 正在检测是否收录...

一、1分钟核心选型:SSE vs WebSocket

先记住一句话:单向推送用SSE,双向交互用WebSocket

核心区别(开发必看)

特性SSE (Server-Sent Events)WebSocket
通信方向服务端 → 客户端 单向服务端 ↔ 客户端 全双工双向
连接类型基于 HTTP 长连接独立协议(ws/wss)
重连机制浏览器自动重连(无需写代码)必须手动实现重连
数据格式纯文本(JSON/字符串)文本/二进制都支持
开发成本极低(PHP原生就能写)高(需要服务端守护进程/扩展)
适用场景通知、日志、实时榜单、进度条聊天、游戏、协同编辑、直播互动
跨域支持(需配置header)支持

什么时候必须选 SSE?

  1. 只需要服务端主动推消息给前端
  2. 不想折腾复杂的 WebSocket 服务
  3. 需要断线自动重连
  4. 技术栈是 PHP/Java/Python 这种传统 Web 语言
  5. 场景:订单通知、系统公告、实时日志、数据监控、上传/导出进度条

什么时候必须选 WebSocket?

  1. 前端需要频繁主动发消息给服务端
  2. 需要低延迟双向交互
  3. 场景:在线聊天、游戏、多人协作、直播弹幕

二、SSE 核心特性 & 实际开发场景

SSE 核心知识点(必须掌握)

  1. Content-Type: text/event-stream:SSE 固定响应头
  2. 长连接:连接保持打开,服务端持续输出数据
  3. 自动重连:断开后浏览器默认3秒重连,无需前端处理
  4. 消息格式:必须以 data: 内容\n\n 结尾(两个换行是协议规定)
  5. 支持自定义事件、消息ID(用于断线续传)

最常用的 SSE 实际业务场景

  1. 实时消息通知(后台有新订单/新消息推前端)
  2. 系统日志实时展示(部署日志、运行日志)
  3. 数据实时刷新(监控面板、实时榜单)
  4. 任务进度条(文件导出、批量处理、上传进度)
  5. 公告/广播推送(全员推送系统消息)

三、PHP 实现 SSE 完整代码示例

环境要求

  • PHP 5.4+ / 7.x / 8.x 均可
  • 关闭输出缓存(关键!)
  • Nginx/Apache 默认配置即可

示例1:基础版 SSE(持续推送时间)

最简单、可直接运行的入门代码

后端:sse_server.php

<?php
// 禁用缓存
header('Cache-Control: no-cache');
// SSE 核心响应头
header('Content-Type: text/event-stream');
header('Connection: keep-alive');
// 跨域配置(前端不同域名必须加)
header('Access-Control-Allow-Origin: *');

// 无限循环推送消息
while (true) {
    $time = date('Y-m-d H:i:s');
    // SSE 固定格式:data: 内容\n\n
    echo "data: 当前服务器时间:{$time}\n\n";
    
    // 刷新缓冲区,把数据推送给前端
    ob_flush();
    flush();
    
    // 每2秒推送一次
    sleep(2);
}
?>

前端:index.html

<!DOCTYPE html>
<html>
<head>
    <title>SSE 基础示例</title>
</head>
<body>
    <h3>实时消息:</h3>
    <div id="msg"></div>

    <script>
        // 创建 SSE 连接
        const sse = new EventSource('sse_server.php');
        
        // 接收消息
        sse.onmessage = function (e) {
            document.getElementById('msg').innerHTML += e.data + '<br>';
        };
        
        // 错误监听(断网/服务挂了会自动重连)
        sse.onerror = function () {
            console.log('连接异常,浏览器自动重连中...');
        };
    </script>
</body>
</html>

运行效果:前端每2秒自动收到服务端时间,断开网络重连后自动恢复。


示例2:JSON 数据推送(开发真实场景)

开发中90%都是推 JSON 数据(订单、通知、列表等)

后端:sse_json.php

<?php
header('Cache-Control: no-cache');
header('Content-Type: text/event-stream');
header('Connection: keep-alive');
header('Access-Control-Allow-Origin: *');

// 模拟订单数据
$orders = [
    ['id' => 1001, 'title' => '新订单', 'price' => 99.9],
    ['id' => 1002, 'title' => '支付成功', 'price' => 199.9]
];

while (true) {
    // 随机取一条订单
    $order = $orders[array_rand($orders)];
    $order['time'] = date('H:i:s');
    
    // 推送 JSON 格式
    echo "data: " . json_encode($order) . "\n\n";

    ob_flush();
    flush();
    sleep(3);
}
?>

前端接收 JSON

const sse = new EventSource('sse_json.php');
sse.onmessage = function (e) {
    // 解析 JSON
    const data = JSON.parse(e.data);
    console.log('订单通知:', data);
    alert(`新订单:${data.title} - ${data.price}元`);
};

示例3:实战场景 —— 任务进度条推送

最常用的业务:文件导出、批量处理、上传进度

后端:sse_progress.php

<?php
header('Cache-Control: no-cache');
header('Content-Type: text/event-stream');
header('Connection: keep-alive');

// 模拟任务进度 0% → 100%
$progress = 0;
while ($progress <= 100) {
    // 推送进度
    echo "data: {$progress}\n\n";
    
    ob_flush();
    flush();
    
    $progress += 10; // 每次加10%
    sleep(1);
}

// 完成信号
echo "data: finish\n\n";
ob_flush();
flush();
?>

前端进度条

<div style="width: 300px; background: #eee;">
    <div id="bar" style="width: 0%; height: 20px; background: green;"></div>
</div>
<p id="text">0%</p>

<script>
const sse = new EventSource('sse_progress.php');
sse.onmessage = function(e) {
    const p = e.data;
    if (p === 'finish') {
        document.getElementById('text').innerText = '任务完成!';
        sse.close(); // 关闭连接
        return;
    }
    document.getElementById('bar').style.width = p + '%';
    document.getElementById('text').innerText = p + '%';
};
</script>

四、PHP + SSE 开发关键避坑点

  1. 必须关闭输出缓存
    ob_flush() + flush() 必须同时写,否则消息推不出去
  2. 无限循环不要占用过高资源
    必须加 sleep(1) 或更长间隔,避免CPU占满
  3. Nginx 环境配置
    如发现消息不推送,在 Nginx 配置加:

    proxy_buffering off;
  4. SSE 是单工通道
    前端不能通过 SSE 发消息给后端(要用AJAX/axios)

五、最终总结(记住这3点就够)

  1. 选型口诀:单向推送选SSE,双向交互选WebSocket
  2. SSE优势:基于HTTP、自动重连、PHP零成本实现、开发极快
  3. 适用场景:通知、日志、实时数据、进度条、广播

你现在可以直接复制上面的代码运行,马上就能体验 SSE 实时推送效果。

0

评论 (0)

取消