本文目录导读:

- 方案一:Server-Sent Events (SSE) — 轻量级,单向推送
- 方案二:WebSocket — 双向实时通信
- 方案三:轮询 (Polling) — 简单但低效
- 方案四:长轮询 (Long Polling) — 兼容性好,延迟较低
- 方案五:第三方推送服务 — 省时省力
- 总结建议
在PHP项目中实现消息推送,通常有以下几种主流方案,你可以根据实时性要求、并发量、技术栈来选择:
Server-Sent Events (SSE) — 轻量级,单向推送
- 原理:客户端通过 HTTP 长连接订阅服务端事件,服务端可以持续推送数据(文本格式)。
- 优点:原生支持,无需引入额外库;基于 HTTP,兼容性好(除了 IE)。
- 缺点:单向(只能服务端推送给客户端);连接数受限于 Web 服务器(如 PHP-FPM 的进程数)。
适用场景:通知、股票价格更新、日志流等不需要客户端发送数据的单向推送。
PHP 示例(使用原生 PHP 作为服务端):
// server.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
// 模拟持续推送数据
while (true) {
$data = ['message' => '当前时间: ' . date('Y-m-d H:i:s'), 'id' => uniqid()];
echo "event: message\n";
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
sleep(2); // 每 2 秒推送一次
}
前端(JS)订阅:
const eventSource = new EventSource('/server.php');
eventSource.addEventListener('message', function(e) {
const data = JSON.parse(e.data);
console.log(data.message);
});
WebSocket — 双向实时通信
- 原理:全双工通信协议,客户端和服务端都可以主动发送数据。
- 优点:真正的实时双向通信;性能高(连接数远高于 SSE)。
- 缺点:需要额外的 WebSocket 服务器(PHP 本身不适合做长连接守护进程,通常用 Node.js、Go、Swoole 等)。
在 PHP 中的实现方式:
方式 A:使用 Swoole(推荐) Swoole 是一个 PHP 扩展,让 PHP 拥有常驻内存、协程、WebSocket 等能力。
# 安装 Swoole 扩展 pecl install swoole
服务端代码(websocket_server.php):
use Swoole\WebSocket\Server;
$server = new Server("0.0.0.0", 9502);
$server->on('open', function (Server $server, $request) {
echo "连接建立: {$request->fd}\n";
});
$server->on('message', function (Server $server, $frame) {
echo "收到消息: {$frame->data}\n";
// 向所有客户端广播
foreach ($server->connections as $fd) {
$server->push($fd, "Server回复: " . $frame->data);
}
});
$server->on('close', function (Server $server, $fd) {
echo "连接关闭: {$fd}\n";
});
$server->start();
客户端(JS):
const ws = new WebSocket('ws://localhost:9502');
ws.onmessage = function(event) {
console.log(event.data);
};
ws.send('Hello from client');
方式 B:使用 Ratchet(基于 ReactPHP) 如果你不想安装 Swoole(非扩展方式),可以用 Ratchet。
composer require cboden/ratchet
轮询 (Polling) — 简单但低效
- 原理:前端每隔几秒向服务器发送 HTTP 请求询问是否有新消息。
- 优点:实现最简单,任何 PHP 环境都能用。
- 缺点:大量无效请求,延迟较高,不推荐用于高实时性场景。
前端(JS):
setInterval(async () => {
const response = await fetch('/get-new-messages.php');
const data = await response.json();
if (data.length > 0) {
// 处理新消息
}
}, 5000); // 每5秒轮询
PHP 服务端:
// get-new-messages.php $lastTime = $_GET['last_time'] ?? 0; // 查询数据库,获取比 $lastTime 更新的消息 $newMessages = getNewMessagesFromDb($lastTime); echo json_encode($newMessages);
长轮询 (Long Polling) — 兼容性好,延迟较低
- 原理:客户端发起请求后,服务端如果有新消息就立即返回,否则保持连接直到有新消息或超时,然后客户端重新发起请求。
- 优点:比普通轮询减少了很多无用请求;无需特殊协议。
- 缺点:仍然占用服务端连接;PHP-FPM 进程数有限,不适合大规模长连接。
示例思路:
// long-polling.php
set_time_limit(0); // 不限制执行时间,但可以根据需要设置
$maxWaitTime = 30; // 最多等待30秒
$startTime = time();
while (true) {
$newMessage = checkForNewMessage();
if ($newMessage) {
echo json_encode($newMessage);
break;
}
if ((time() - $startTime) > $maxWaitTime) {
echo json_encode(['status' => 'timeout']);
break;
}
sleep(1); // 避免 CPU 空转
}
第三方推送服务 — 省时省力
- 原理:使用专业的推送服务(如 Pusher、Firebase Cloud Messaging、GoEasy等),PHP 作为后端只负责触发推送。
- 优点:几乎零开发成本;高可用、高并发;支持更多端(Web、移动端、微信小程序等)。
- 缺点:需要付费;数据经过第三方。
示例(使用 Pusher):
composer require pusher/pusher-php-server
PHP 触发推送:
$pusher = new Pusher\Pusher('key', 'secret', 'app_id');
$pusher->trigger('my-channel', 'my-event', ['message' => 'Hello World']);
前端监听:
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
<script>
var pusher = new Pusher('key', { cluster: 'mt1' });
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert(data.message);
});
</script>
总结建议
| 需求场景 | 推荐方案 | 备注 |
|---|---|---|
| 简单通知、页面内更新 | SSE | 最简单,原生支持 |
| 游戏、聊天室、协同编辑 | Swoole WebSocket | 性能最佳,需安装扩展 |
| 不想改服务器环境 | 长轮询 或 第三方服务 | 兼容性好 |
| 高并发、稳定可靠 | 第三方服务(Pusher等) | 省心但付费 |
| 企业级项目、已有 Swoole 团队 | Swoole WebSocket | 自建可控 |
特别提醒:PHP 传统的 php-fpm 模式下,每个请求都是独立的进程,不适合长连接(SSE 和长轮询会占用进程),如果并发需求高,建议使用 Swoole 或 Workerman 这类常驻内存的框架。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播