Long polling vs WebSocket 在 PHP 中:如何为实时项目选择

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

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

开始课程

引言:为什么您的网站在实时交互时“卡顿”?

\n\n

想象一下,您登录一个外汇网站,但美元汇率只有在刷新页面后才会更新。或者您在聊天中发送了一条消息,对方却在 10 秒后才看到。熟悉吗?这是任何试图让应用变得“鲜活”的开发者的痛点。

\n\n

在 PHP 的世界里,每个请求的生命周期都很短暂,实现实时功能是一项颇具挑战的任务。有两种主要方法可以解决这个问题:Long polling 和 WebSocket。对于您的 PHP 项目,应该选择哪一种?让我们通过实际的代码示例,直截了当地进行分析。

\n\n

PHP 中的 Long polling 是什么?一个带有秘密的长请求

\n\n

Long polling 是一种巧妙的技巧,它利用普通的 HTTP 请求来模拟实时连接。客户端向服务器发送一个请求,但服务器不会立即响应。它会保持连接打开,直到有新事件发生(例如,聊天中的新消息)。一旦事件发生,服务器就会发送响应,客户端处理该响应后,立即发起一个新的“长”请求。

\n\n

它在 PHP 中如何工作:一个简单的例子

\n\n

假设我们有一个简单的聊天应用。客户端发送一个 AJAX 请求到 PHP 脚本,该脚本在一个循环中“挂起”,直到数据库中出现新消息。

\n\n
<?php\n// long_polling.php\nheader('Content-Type: application/json');\nheader('Cache-Control: no-cache');\n\n$lastMessageId = $_GET['last_id'] ?? 0;\n$timeout = 30; // 最多等待 30 秒\n$startTime = time();\n\nwhile (time() - $startTime < $timeout) {\n    // 模拟数据库检查(实际应用中为 MySQL/PostgreSQL 查询)\n    $newMessages = getNewMessagesFromDB($lastMessageId);\n    \n    if (!empty($newMessages)) {\n        echo json_encode([\n            'status' => 'success',\n            'messages' => $newMessages\n        ]);\n        exit;\n    }\n    \n    // 休眠 1 秒,避免 CPU 过载\n    sleep(1);\n}\n\n// 如果 30 秒内没有新消息\necho json_encode(['status' => 'timeout', 'messages' => []]);\nexit;\n?>
\n\n

在客户端(JavaScript)中,代码如下:

\n\n
function startLongPolling(lastId) {\n    fetch('/long_polling.php?last_id=' + lastId)\n        .then(response => response.json())\n        .then(data => {\n            if (data.status === 'success') {\n                data.messages.forEach(msg => addMessageToChat(msg));\n                startLongPolling(data.messages[data.messages.length - 1].id);\n            } else {\n                startLongPolling(lastId); // 超时——只需重新启动\n            }\n        })\n        .catch(() => setTimeout(() => startLongPolling(lastId), 1000));\n}\n
\n\n

PHP 中 Long polling 的优点

\n
    \n
  • 实现简单 — 无需额外的服务器或库。一切都可以在普通的 Apache/Nginx + PHP-FPM 上运行。
  • \n
  • 兼容性好 — 任何支持 HTTP 的地方都能工作。无需担心代理或企业防火墙问题。
  • \n
  • 入门门槛低 — 如果您了解 PHP 和 AJAX,您就可以实现 Long polling。
  • \n
\n\n

Long polling 的缺点

\n
    \n
  • 服务器负载高 — 每个“长”请求都会占用一个 PHP-FPM 进程。如果有 1000 个用户,您就需要 1000 个进程。
  • \n
  • 延迟高 — 最小延迟为 1 秒(由于 sleep)。如果减少 sleep 时间,CPU 负载会急剧上升。
  • \n
  • 扩展困难 — Long polling 与负载均衡器配合不佳(需要将用户绑定到特定服务器)。
  • \n
\n\n

PHP 中的 WebSocket:真正的实时,无需妥协

\n\n

WebSocket 是一个基于 TCP 的全双工通信通道。在通过 HTTP 完成握手后,

博客

书籍推荐