本文目录导读:

- 方案一:WebSocket(推荐)
- 方案二:SSE (Server-Sent Events)
- 方案三:短轮询 + HTTP
- 方案四:第三方推送服务
- 方案五:长轮询 (Long Polling)
- 综合推荐
- 实际项目最佳实践
在 PHP 项目中实现实时通知功能,通常需要结合前端实时通信技术和后端消息推送机制,由于 PHP 本身是同步阻塞的 HTTP 协议,无法原生维持长连接,因此需要借助以下主流方案:
WebSocket(推荐)
这是最直接、最实时的方案,PHP 服务端通过 WebSocket 协议与客户端建立双向长连接。
技术选型
- Swoole:高性能异步 PHP 扩展,支持 WebSocket 服务器
- Workerman:纯 PHP 实现的多进程 socket 框架
- Ratchet:基于 ReactPHP 的 WebSocket 组件库
实现步骤(以 Workerman 为例)
安装 Workerman
composer require workerman/workerman
创建 WebSocket 服务端
// server.php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
$ws_worker = new Worker('websocket://0.0.0.0:8080');
// 维护用户连接映射
$user_connections = [];
$ws_worker->onConnect = function ($connection) {
echo "新连接\n";
};
$ws_worker->onMessage = function ($connection, $data) use (&$user_connections) {
$msg = json_decode($data, true);
// 客户端发送认证消息 {'type': 'auth', 'user_id': 1}
if ($msg['type'] === 'auth') {
$user_connections[$msg['user_id']] = $connection;
$connection->userId = $msg['user_id'];
echo "用户 {$msg['user_id']} 已认证\n";
}
// 其他业务消息处理...
};
$ws_worker->onClose = function ($connection) use (&$user_connections) {
if (isset($connection->userId)) {
unset($user_connections[$connection->userId]);
echo "用户 {$connection->userId} 断开\n";
}
};
Worker::runAll();
客户端 JS 代码
// 前端连接 WebSocket
let ws = new WebSocket('ws://your-domain.com:8080');
ws.onopen = function() {
// 发送用户认证
ws.send(JSON.stringify({
type: 'auth',
user_id: 123 // 当前登录用户ID
}));
};
ws.onmessage = function(event) {
let data = JSON.parse(event.data);
console.log('收到通知:', data);
showNotification(data);
};
从 PHP 业务代码推送消息 需要将 WebSocket 服务端与 HTTP 端连通,常见做法:
- 使用内部消息队列(Redis Pub/Sub)
- 直接调用 WebSocket 服务端 API
// 在 Laravel/Symfony 等框架中
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 当有新通知时发布到 Redis 频道
$redis->publish('notification_channel', json_encode([
'user_id' => 123, => '新消息',
'content' => '有人评论了你的文章'
]));
同时在 WebSocket 服务端订阅该频道:
// 在 Workerman 进程初始化时
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->subscribe(['notification_channel'], function($redis, $channel, $msg) use ($ws_worker) {
$data = json_decode($msg, true);
if (isset($user_connections[$data['user_id']])) {
$user_connections[$data['user_id']]->send(json_encode([
'type' => 'notification',
'data' => $data
]));
}
});
SSE (Server-Sent Events)
适合单向推送(服务端→客户端),实现简单,原生 HTML5 支持。
实现步骤
创建 SSE 端点的 PHP 脚本
// sse.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
$userId = $_GET['user_id']; // 实际应通过认证获取
while (true) {
// 从数据库/缓存获取最新通知
$notifications = getNewNotifications($userId);
if (!empty($notifications)) {
echo "data: " . json_encode($notifications) . "\n\n";
ob_flush();
flush();
}
sleep(2); // 轮询间隔
}
客户端 JS 代码
let eventSource = new EventSource('/sse.php?user_id=123');
eventSource.onmessage = function(event) {
let data = JSON.parse(event.data);
showNotification(data);
};
eventSource.onerror = function() {
console.error('SSE 连接断开');
};
缺点:PHP 脚本会长时间占用进程,高并发场景不推荐。
短轮询 + HTTP
适合对实时性要求不高的场景,实现最简单。
function pollNotifications() {
fetch('/api/notifications?last_id=0')
.then(res => res.json())
.then(data => {
if (data.length > 0) {
showNotifications(data);
}
});
setTimeout(pollNotifications, 5000); // 5秒轮询一次
}
第三方推送服务
对于企业级应用,直接使用成熟的推送服务:
| 服务 | 特点 | 适合场景 |
|---|---|---|
| Pusher | 原生 WebSocket,免费额度 | 快速原型、中小项目 |
| Firebase Cloud Messaging | 支持移动端和 Web | 跨平台通知 |
| Socket.IO | 需要搭配 Node.js | 复杂实时交互 |
| Mercure | 基于 SSE 的现代协议 | Symfony 生态推荐 |
长轮询 (Long Polling)
传统方案,在 PHP 中通过无限循环 + 超时实现:
set_time_limit(0);
$start = time();
while (time() - $start < 30) { // 最长等待30秒
$notifications = getNewNotifications($userId);
if (!empty($notifications)) {
echo json_encode($notifications);
exit;
}
usleep(500000); // 0.5秒检查一次
}
echo json_encode([]); // 超时返回空
综合推荐
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 高并发实时通讯 | WebSocket + Swoole/Workerman | 性能最优,双向通信 |
| 简单单向通知 | SSE | 实现简单,无需额外服务 |
| 快速原型/小项目 | Pusher/Firebase | 开箱即用,零运维 |
| 已有 Laravel 项目 | Laravel Echo + Pusher/Redis | 官方支持,集成度高 |
| 传统 PHP 项目 | 长轮询 | 纯 PHP 实现,无需扩展 |
实际项目最佳实践
以常见 Web 项目为例,推荐组合方案:
- WebSocket 服务器(Swoole/Workerman)
- Redis Pub/Sub 作为内部消息通道
- HTTP 业务代码发布通知到 Redis
- WebSocket 服务器订阅 Redis 并推送给用户
架构图:
[用户A] ←→ WebSocket服务器 ←→ Redis Pub/Sub ← PHP请求处理
[用户B] ←→ WebSocket服务器 ←→ Redis Pub/Sub ← 定时任务/其他系统
这样既保留了 PHP 的简易开发,又能获得实时推送能力,适合中大型项目。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播