php 实现comet
PHP 实现 Comet 技术
Comet 是一种基于 HTTP 长连接的服务器推送技术,允许服务器实时向客户端推送数据。PHP 可以通过以下方法实现 Comet。
长轮询(Long Polling)
长轮询是 Comet 的一种常见实现方式。客户端发送请求后,服务器保持连接打开,直到有新数据或超时。
// 服务器端代码
while (true) {
$data = getNewData(); // 检查新数据
if ($data) {
echo json_encode($data);
break;
}
sleep(1); // 避免 CPU 过度占用
flush(); // 确保数据及时发送
}
客户端使用 JavaScript 发起请求,并在收到响应后立即再次请求:
function longPoll() {
fetch('comet.php')
.then(response => response.json())
.then(data => {
console.log(data);
longPoll(); // 递归调用
});
}
longPoll();
无限循环(Infinite Loop)
通过无限循环保持连接开放,适用于需要持续推送的场景。需注意设置适当的超时和刷新。
set_time_limit(0); // 取消脚本执行时间限制
while (true) {
$data = checkForUpdates();
if ($data) {
echo json_encode($data);
ob_flush();
flush();
}
usleep(100000); // 微秒级延迟,减少 CPU 负载
}
使用 WebSocket 替代
虽然 PHP 不是 WebSocket 的最佳选择,但可以通过库(如 Ratchet)实现:
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class CometHandler implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {}
public function onClose(ConnectionInterface $conn) {}
public function onError(ConnectionInterface $conn, \Exception $e) {}
public function onMessage(ConnectionInterface $from, $msg) {
$from->send("Server: " . $msg);
}
}
$server = new \Ratchet\App('localhost', 8080);
$server->route('/comet', new CometHandler());
$server->run();
使用 Server-Sent Events (SSE)
SSE 是 HTML5 标准,适合单向服务器推送:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
$data = getUpdates();
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
sleep(1);
}
客户端通过 EventSource 接收:
const source = new EventSource('sse.php');
source.onmessage = (e) => console.log(e.data);
注意事项
- 性能问题:长连接会占用服务器资源,需合理配置超时和并发限制。
- 缓冲控制:使用
ob_flush()和flush()确保数据及时发送。 - 超时设置:通过
set_time_limit(0)避免脚本被终止。 - 替代方案:考虑使用专业的实时技术如 WebSocket 或 MQTT。
以上方法可根据实际需求选择,长轮询和 SSE 适合简单场景,WebSocket 适合高性能需求。







