php实现长轮询
PHP 实现长轮询的方法
长轮询(Long Polling)是一种模拟实时通信的技术,客户端发起请求后,服务器在有数据更新时才响应,否则保持连接直到超时。以下是PHP实现长轮询的具体方法。
基础实现逻辑
客户端通过AJAX向服务器发送请求,服务器脚本检查数据更新状态。如果没有新数据,脚本休眠(sleep)一段时间后重新检查,直到有新数据或超时。
// 服务器端代码(long_polling.php)
$timeout = 30; // 超时时间(秒)
$startTime = time();
while (true) {
// 检查数据是否有更新(示例:检查数据库或文件)
$newDataAvailable = checkForNewData();
if ($newDataAvailable) {
echo json_encode(['data' => $newData]);
break;
}
// 检查是否超时
if (time() - $startTime >= $timeout) {
echo json_encode(['timeout' => true]);
break;
}
usleep(500000); // 休眠0.5秒减少CPU负载
}
客户端代码示例
客户端使用JavaScript发起请求,并在收到响应后处理数据或重新发起请求。

function fetchData() {
fetch('long_polling.php')
.then(response => response.json())
.then(data => {
if (data.timeout) {
console.log('请求超时,重新发起长轮询');
} else {
console.log('收到新数据:', data);
// 处理数据逻辑
}
fetchData(); // 递归调用实现持续轮询
});
}
fetchData(); // 初始化请求
优化建议
减少服务器负载
通过调整休眠时间(如usleep)平衡实时性和性能,避免频繁检查数据源。
数据库优化
若数据源为数据库,使用SELECT ... FOR UPDATE或缓存机制减少查询压力。

连接管理
设置合理的PHP脚本执行时间(set_time_limit),避免脚本无限运行。
set_time_limit(35); // 略大于超时时间
处理连接中断
客户端需捕获网络错误并自动重连。
function fetchData() {
fetch('long_polling.php')
.then(response => {
if (!response.ok) throw new Error('网络错误');
return response.json();
})
.catch(error => {
console.error('长轮询失败:', error);
setTimeout(fetchData, 3000); // 3秒后重试
})
.then(data => {
// 正常数据处理逻辑
fetchData();
});
}
注意事项
- 避免阻塞:确保其他PHP请求不受长轮询脚本影响,可通过独立服务或队列实现。
- 会话锁定:若使用
session_start(),需调用session_write_close()释放锁,避免阻塞其他请求。
session_start();
// 会话操作完成后立即释放
session_write_close();






