本文目录导读:

在 PHP 项目中实现消息推送,根据应用场景(如实时网页消息、服务端事件通知、移动端推送)的不同,主要有以下几种主流实现方案:
使用 WebSocket(推荐用于实时双向通信)
适用于聊天、在线协作、实时通知等需要与服务器保持长连接的场景。
- 原理:在客户端和服务器之间建立一个全双工的长连接,服务器可以主动向客户端推送数据。
- PHP 实现方案:
- 原生 PHP + Swoole / Workerman:这是 PHP 实现 Websocket 最常用的方式,Swoole 和 Workerman 是常驻内存的 PHP 扩展/框架,可以突破传统 PHP 请求-响应模式的限制。
- Swoole:
Swoole\WebSocket\Server - Workerman:
Workerman\Connection\WebsocketConnection
- Swoole:
- 商业云服务:使用 Pusher、Ably 或 腾讯云、阿里云的 WebSocket 服务。
- 原生 PHP + Swoole / Workerman:这是 PHP 实现 Websocket 最常用的方式,Swoole 和 Workerman 是常驻内存的 PHP 扩展/框架,可以突破传统 PHP 请求-响应模式的限制。
- 示例(Workerman 服务器端代码):
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use Workerman\Lib\Timer;
// 创建一个 Websocket 服务器
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 启动 4 个进程
$ws_worker->count = 4;
// 连接建立时
$ws_worker->onConnect = function($connection) {
echo "新连接\n";
};
// 收到消息时
$ws_worker->onMessage = function($connection, $data) use ($ws_worker) {
// 向所有客户端发送消息(推送)
foreach($ws_worker->connections as $client) {
$client->send($data);
}
};
// 连接断开时
$ws_worker->onClose = function($connection) {
echo "连接断开\n";
};
// 运行 worker
Worker::runAll();
- 客户端 JS:
var ws = new WebSocket("ws://your_server_ip:2346");
ws.onmessage = function (e) {
console.log("收到消息: " + e.data);
};
ws.send("Hello server!");
使用 Server-Sent Events(适合单向推送)
适用于需要服务器单向推送消息给浏览器,但不需要客户端频繁发送数据的场景(如新闻推送、股票行情、日志监控)。
- 原理:客户端通过 HTTP 连接向服务器发送一个
EventSource请求,服务器端持续输出text/event-stream格式的数据。 - 优势:实现简单,基于标准 HTTP 协议,不需要额外库(如 Swoole)或修改 Apache/Nginx 配置。
- PHP 实现(传统 PHP 脚本):
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
// 模拟数据推送循环
$counter = 0;
while (true) {
$data = json_encode(['msg' => 'Hello ' . $counter, 'time' => date('H:i:s')]);
echo "data: {$data}\n\n";
ob_flush();
flush();
sleep(2); // 每 2 秒推送一次
$counter++;
}
- 客户端 JS:
var source = new EventSource("http://your_server.com/sse.php");
source.onmessage = function (event) {
var data = JSON.parse(event.data);
console.log(data.msg);
};
- 注意:每个连接会占用一个 PHP-FPM 进程,高并发时容易撑爆,常用于低并发的管理后台或监控页面。
使用轮询机制
适用于实时性要求不高的场景(如每 3-5 秒检查一次是否有新消息)。
- 原理:客户端定时(通过
setInterval或setTimeout)向服务器发送 HTTP 请求,服务器检查是否有新数据并返回。 - 缺点:效率低,浪费带宽和服务器资源,有明显延迟。
结合消息队列实现异步推送
适用于需要解耦、高吞吐量的场景(如用户下单后通知多个系统)。
- 流程:PHP 业务逻辑将推送任务写入 Redis 列表(List)或 RabbitMQ/腾讯 CMQ 等消息队列,由独立的后台消费者进程(常驻 PHP 脚本)读取并发送。
- 生产者:用户注册后,PHP 业务代码
rpush('push_queue', json_encode(['type'=>'welcome', 'user_id'=>123]))。 - 消费者:一个使用 Workerman 或 Swoole 编写的常驻进程,从队列中取出数据,调用 WebSocket 或第三方推送 SDK 进行发送。
- 生产者:用户注册后,PHP 业务代码
移动端或跨平台推送
如果推送到手机 App(iOS/Android 或微信/钉钉),不能直接建立长连接。
- 方案:PHP 调用第三方推送服务 SDK。
- 极光推送(JPush)
- 个推
- 腾讯云移动推送(TPNS)
- Firebase Cloud Messaging(FCM)
- 阿里云移动推送
- 微信小程序 / 公众号模板消息(通过微信 API)
总结与选型建议
| 场景 | 推荐技术 | PHP 实现方式 | 并发能力 |
|---|---|---|---|
| 实时性高、双向(IM,实时协作) | WebSocket | Swoole / Workerman(或 Pusher 等云服务) | 高(长连接复用) |
| 实时性高、服务器单向推送(监控屏、大盘) | SSE | 配合 Nginx 或独立常驻进程 | 中等(每个连接一个进程) |
| 实时性较低、兼容性高(老旧系统) | AJAX 轮询 | 普通 PHP 脚本(短请求) | 低(大量请求开销) |
| 异步解耦、高吞吐(订单通知等) | 消息队列 + 消费进程 | Redis/RabbitMQ + Workerman/Swoole | 高 |
| 移动端 App / 服务号 | 第三方 SDK | 调用 HTTP API(如 JPush SDK) | 由第三方保障 |
核心建议: 如果是在传统 PHP(nginx+php-fpm)下,不建议直接用 PHP 脚本做长连接轮询或 SSE(会快速占满进程),最佳实践是引入 Swoole 或 Workerman 作为独立的推送服务,主业务 PHP 代码只需往 Redis 或消息队列里写任务即可。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播