Long-Polling, WebSockets, SSE 和 Comet 在 PHP 中的全面解析与代码示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

“实时”数据更新背后隐藏着什么?深入解析实时技术

\n\n

您是否曾好奇,聊天应用如何实现消息即时送达,或者股票行情如何自动刷新?传统的 HTTP 请求(浏览器向服务器发起请求,服务器响应)在此场景下显得缓慢且低效。我们需要 实时 技术的魔力。

\n\n

在 Stack Overflow 上,“什么是 Long-Polling、Websockets、Server-Sent Events (SSE) 和 Comet?”这个问题获得了数千次浏览。这说明对这些术语感到困惑是很常见的。今天,我们将逐一梳理,编写真实的 PHP 代码,并理解何时使用哪种技术。

\n\n

我们不会使用复杂的框架——仅使用纯 PHP 和几个流行的库。开始吧!

\n\n

1. HTTP Polling(普通轮询)——技术之祖

\n\n

在讨论高级技术之前,我们先回顾一下基础的 轮询。客户端(JavaScript)每隔 N 秒向服务器发送一次请求。服务器响应:“无新数据”或“这是数据”。

\n\n

PHP 代码(服务器端):

\n
<?php\n// polling_server.php\nheader('Content-Type: application/json');\n\n// 模拟获取数据\n$data = ['message' => 'Hello at ' . date('H:i:s')];\necho json_encode($data);\n
\n\n

客户端代码(JavaScript):

\n
setInterval(() => {\n    fetch('polling_server.php')\n        .then(response => response.json())\n        .then(data => console.log(data.message));\n}, 3000); // 每 3 秒一次
\n\n

优点:简单。缺点:大量冗余请求,服务器负载高,延迟可达 N 秒。对于聊天应用来说,这不可接受。

\n\n

2. Long-Polling——优雅的变通方案

\n\n

Long-Polling 是轮询的改进版本。客户端发起一个 HTTP 请求,如果服务器没有数据,不会立即响应。它保持连接打开(处于等待状态)。一旦数据可用,服务器发送响应并关闭连接。客户端立即发起新的请求。

\n\n

从客户端角度看,这是一个普通的 fetch。从服务器角度看,需要能够“休眠”并“唤醒”。

\n\n

Long-Polling 的 PHP 示例

\n
<?php\n// long_polling.php\nheader('Content-Type: application/json');\nheader('Cache-Control: no-cache');\n\n// 模拟等待新消息(例如,来自文件或数据库)\n$lastCheck = time();\n$timeout = 30; // 最长等待 30 秒\n\nwhile (time() - $lastCheck < $timeout) {\n    // 检查是否有新数据\n    $newData = checkForNewMessages(); // 您的函数\n    if ($newData !== null) {\n        echo json_encode(['status' => 'ok', 'data' => $newData]);\n        exit;\n    }\n    // 休眠 1 秒,避免占用 CPU\n    sleep(1);\n}\n\n// 如果 30 秒内无数据,返回空响应\necho json_encode(['status' => 'timeout', 'data' => null]);\n
\n\n

重要提示: 在实际项目中,将 sleep(1) 替换为 usleep(500000)(0.5 秒),并使用非阻塞检查(例如,对文件使用 filemtime(),或对数据库使用带超时的 SELECT ... FOR UPDATE)。

\n\n

应用场景:旧式聊天、不支持 WebSockets 的网站通知。缺点:连接数量仍然很多,服务器资源消耗在“挂起”的请求上。

\n\n

3. Server-Sent Events (SSE)——服务器到客户端的单向通道

\n\n

SSE(Server-Sent Events) 是 HTML5 内置的技术。服务器可以随时向客户端发送数据,但仅限单向(服务器 → 客户端)。客户端使用 JavaScript 中的 EventSource。

\n\n

SSE 非常适合:新闻推送、股票行情、日志、通知。

\n\n

PHP 代码(服务器端):

\n
<?php\n// sse_server.php\nheader('Content-Type: text/event-stream');\nheader('Cache-Control: no-cache'                

博客

书籍推荐