php 实现comet
PHP 实现 Comet 技术
Comet 是一种服务器推送技术,允许服务器实时向客户端推送数据,而不需要客户端频繁轮询。以下是几种 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();
使用 WebSocket
WebSocket 是更高效的实时通信协议,但需要服务器和客户端支持。PHP 可以通过库如 Ratchet 实现 WebSocket。
安装 Ratchet:

composer require cboden/ratchet
服务器端代码:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();
客户端 JavaScript:
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = (event) => {
console.log(event.data);
};
使用 Server-Sent Events (SSE)
SSE 是 HTML5 的一种技术,允许服务器单向推送数据到客户端。

服务器端 PHP:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
$data = getNewData();
if ($data) {
echo "data: " . json_encode($data) . "\n\n";
flush();
}
sleep(1);
}
客户端 JavaScript:
const eventSource = new EventSource('sse.php');
eventSource.onmessage = (event) => {
console.log(event.data);
};
使用共享内存或文件锁
对于高并发场景,可以使用共享内存或文件锁来管理数据推送。
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, "c", 0644, 100);
while (true) {
$data = shmop_read($shm_id, 0, shmop_size($shm_id));
if ($data) {
echo $data;
shmop_delete($shm_id);
break;
}
sleep(1);
}
shmop_close($shm_id);
注意事项
- 性能优化:长轮询和 SSE 会占用服务器资源,需合理设置超时和并发限制。
- 兼容性:WebSocket 和 SSE 需要现代浏览器支持,长轮询兼容性更好。
- 安全性:确保实时通信接口有适当的身份验证和防滥用机制。
以上方法可以根据具体需求选择,长轮询适合简单场景,WebSocket 和 SSE 适合高性能实时应用。






