本文目录导读:

在PHP项目中实现实时看板,最推荐的方式是使用 WebSocket(配合 Laravel Echo、Pusher 或 Ratchet),或者采用 Server-Sent Events (SSE) 以及短轮询。
以下是几种主流实现方案的详细对比与代码示例:
WebSocket (推荐,性能最好)
这是实现实时更新的标准方案,PHP 本身不支持长连接,因此需要借助第三方服务或扩展。
子方案 A:使用 Pusher (最省心,适合快速开发)
Pusher 是一个 SaaS(软件即服务)服务,提供 WebSocket 基础设施。
步骤:
-
安装包:
composer require pusher/pusher-php-server npm install --save laravel-echo pusher-js
-
后端推送:
// 看板数据更新时 $options = [ 'cluster' => 'ap1', 'useTLS' => true ]; $pusher = new Pusher\Pusher('key', 'secret', 'app_id', $options); // 广播到 'dashboard' 频道 $pusher->trigger('dashboard-channel', 'update-event', [ 'newData' => $data // 从数据库获取的最新看板数据 ]); -
前端订阅 (JavaScript):
import Echo from 'laravel-echo'; window.Pusher = require('pusher-js'); const echo = new Echo({ broadcaster: 'pusher', key: 'your-key', cluster: 'ap1' }); // 订阅频道,收到新数据后更新看板 echo.channel('dashboard-channel') .listen('update-event', (e) => { // 使用 e.newData 更新前端总览、图表等 renderDashboard(e.newData); });
子方案 B:使用 Ratchet (自建WebSocket,完全控制)
适合需要完全控制不想依赖第三方服务的场景。
服务端 (PHP CLI脚本运行):
<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
class DashboardServer implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// 存储新连接
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
// 收到消息(比如客户端请求刷新)
$newData = fetchLatestDataFromDB(); // 从数据库获取最新数据
// 如果是广播,可以发给所有客户端
foreach ($this->clients as $client) {
$client->send(json_encode($newData));
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
// 启动服务器 (端口 8080)
$server = IoServer::factory(
new HttpServer(
new WsServer(
new DashboardServer()
)
),
8080
);
$server->run();
前端:
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => {
// 连接建立后可以发送请求
ws.send(JSON.stringify({action: 'subscribe'}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
renderDashboard(data); // 更新看板
};
Server-Sent Events (更适合单向推送)
SSE 比 WebSocket 更简单,PHP 用原生代码即可实现。
PHP 端点 (sse.php):
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
// 从数据库、Redis或文件获取最新数据
$data = fetchLatestDashboardData();
// 发送事件
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
// 每5秒推送一次,防止PHP进程占满CPU
sleep(5);
}
前端:
const evtSource = new EventSource('sse.php');
evtSource.onmessage = function(event) {
const data = JSON.parse(event.data);
renderDashboard(data); // 实时更新看板
};
缺点:是单向的(服务器到客户端),SSE 连接数多时会消耗大量 PHP 进程。
长轮询 (最简单,但不够实时)
如果项目规模很小,或无法使用 WebSocket,可以用传统的 AJAX 轮询。
PHP 后端 (ajax_endpoint.php):
<?php // 每次请求都返回最新数据 $data = fetchLatestDashboardData(); echo json_encode($data);
前端:
function poll() {
$.ajax({
url: 'ajax_endpoint.php',
success: function(data) {
renderDashboard(data);
},
complete: function() {
// 请求完成后等待2秒再发下一次请求
setTimeout(poll, 2000);
}
});
}
poll();
缺点:延迟较高(2秒),服务器压力大。
数据库层面的实时通知
无论你用哪种方式,数据触发器通常需要配合 Redis 发布/订阅 或多进程:
- 数据源:你的业务逻辑(例如订单新增、KPI变化)更新数据库。
- 触发通知:业务代码在写库后,立即向 Redis 发布消息:
// 更新数据库后 $redis->publish('dashboard-updates', json_encode($newData)); - WebSocket 服务器(如 Ratchet)可以订阅 Redis 频道,收到消息后广播给所有连接的前端。
这样你普通的 PHP 业务代码只管写 Redis 消息,WebSocket 服务器负责转发。
| 项目规模/复杂度 | 推荐方案 | 理由 |
|---|---|---|
| 中小项目,快速上线 | Pusher 或 Ably | 几分钟集成,无需运维 WebSocket 服务 |
| 公司内部系统,有可控服务器 | 自建 Ratchet + Redis | 完全控制,无费用,性能较好 |
| 只有 PHP 环境,不想额外进程 | SSE (Server-Sent Events) | 最简单的真正实时方案,单向推送够用 |
| 临时演示或低负载 | 长轮询 (Long Polling) | 无需任何扩展,延迟可接受 |
补充提醒:如果看板上主要是实时图表数据(如监控、销售额),建议将聚合计算逻辑尽量放在数据库或 Redis 中,推送时直接推送最终计算结果,而不是原始数据,这样看板更新更快。