php 实现长轮询
PHP 实现长轮询
长轮询(Long Polling)是一种模拟实时通信的技术,客户端发送请求后,服务器在有数据更新时才返回响应,否则保持连接直到超时。以下是实现方法:
客户端 JavaScript 部分
使用 fetch 或 XMLHttpRequest 发起请求,并在响应返回后立即发起下一次请求:

function longPoll() {
fetch('long_polling.php')
.then(response => response.json())
.then(data => {
console.log("收到数据:", data);
longPoll(); // 递归调用保持持续监听
})
.catch(error => {
console.error("请求失败:", error);
setTimeout(longPoll, 3000); // 失败后延迟重试
});
}
longPoll(); // 启动长轮询
服务器端 PHP 部分
通过循环检查数据变化或等待超时,避免频繁请求:

<?php
header('Content-Type: application/json');
set_time_limit(0); // 禁用脚本超时
$dataFile = 'data.json';
$timeout = 30; // 长轮询超时时间(秒)
$startTime = time();
while (true) {
// 检查数据是否更新(示例:文件修改时间)
$lastModified = filemtime($dataFile);
if ($lastModified > ($_GET['lastUpdate'] ?? 0)) {
$data = json_decode(file_get_contents($dataFile), true);
echo json_encode(['data' => $data, 'timestamp' => $lastModified]);
break;
}
// 超时处理
if (time() - $startTime >= $timeout) {
echo json_encode(['data' => null, 'timestamp' => $lastModified]);
break;
}
usleep(500000); // 减少CPU占用(0.5秒间隔检查)
}
?>
数据更新触发
通过其他接口或文件操作更新数据源(如 data.json):
<?php
file_put_contents('data.json', json_encode(['message' => '新数据']));
touch('data.json'); // 更新文件修改时间
?>
优化建议
- 连接管理:确保服务器配置(如 Nginx/Apache)允许长连接,调整
keepalive_timeout。 - 错误处理:客户端需处理网络中断,实现自动重连逻辑。
- 性能考虑:高并发时改用事件驱动架构(如 Swoole)或 WebSocket。
替代方案
若需更高实时性,可考虑以下技术:
- WebSocket:全双工通信,适合高频更新场景。
- Server-Sent Events (SSE):单向服务器推送,兼容性优于 WebSocket。
以上代码提供了基础实现框架,可根据实际需求调整超时时间和数据检查逻辑。






