PHP项目怎样实现消息推送?

wen PHP项目 9

本文目录导读:

PHP项目怎样实现消息推送?

  1. 使用 WebSocket(推荐用于实时双向通信)
  2. 使用 Server-Sent Events(适合单向推送)
  3. 使用轮询机制
  4. 结合消息队列实现异步推送
  5. 移动端或跨平台推送
  6. 总结与选型建议

在 PHP 项目中实现消息推送,根据应用场景(如实时网页消息、服务端事件通知、移动端推送)的不同,主要有以下几种主流实现方案:

使用 WebSocket(推荐用于实时双向通信)

适用于聊天、在线协作、实时通知等需要与服务器保持长连接的场景。

  • 原理:在客户端和服务器之间建立一个全双工的长连接,服务器可以主动向客户端推送数据。
  • PHP 实现方案
    • 原生 PHP + Swoole / Workerman:这是 PHP 实现 Websocket 最常用的方式,Swoole 和 Workerman 是常驻内存的 PHP 扩展/框架,可以突破传统 PHP 请求-响应模式的限制。
      • SwooleSwoole\WebSocket\Server
      • WorkermanWorkerman\Connection\WebsocketConnection
    • 商业云服务:使用 Pusher、Ably 或 腾讯云、阿里云的 WebSocket 服务。
  • 示例(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 秒检查一次是否有新消息)。

  • 原理:客户端定时(通过 setIntervalsetTimeout)向服务器发送 HTTP 请求,服务器检查是否有新数据并返回。
  • 缺点:效率低,浪费带宽和服务器资源,有明显延迟。

结合消息队列实现异步推送

适用于需要解耦、高吞吐量的场景(如用户下单后通知多个系统)。

  • 流程:PHP 业务逻辑将推送任务写入 Redis 列表(List)或 RabbitMQ/腾讯 CMQ 等消息队列,由独立的后台消费者进程(常驻 PHP 脚本)读取并发送。
    • 生产者:用户注册后,PHP 业务代码 rpush('push_queue', json_encode(['type'=>'welcome', 'user_id'=>123]))
    • 消费者:一个使用 Workerman 或 Swoole 编写的常驻进程,从队列中取出数据,调用 WebSocket 或第三方推送 SDK 进行发送。

移动端或跨平台推送

如果推送到手机 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(会快速占满进程),最佳实践是引入 SwooleWorkerman 作为独立的推送服务,主业务 PHP 代码只需往 Redis 或消息队列里写任务即可。

抱歉,评论功能暂时关闭!