php实现推送消息推送
PHP 实现消息推送的方法
使用 WebSocket 实现实时推送
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,适用于实时消息推送。
安装 Ratchet 库(WebSocket 实现):
composer require cboden/ratchet
创建 WebSocket 服务器:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();
创建消息处理类:
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($from !== $client) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
使用 Server-Sent Events (SSE)
SSE 是一种服务器向浏览器推送消息的简单方式。
服务端实现:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
function sendMsg($id, $msg) {
echo "id: $id" . PHP_EOL;
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
while(true) {
$serverTime = time();
sendMsg($serverTime, 'server time: ' . date("h:i:s", $serverTime));
sleep(1);
}
客户端实现:

var evtSource = new EventSource("sse.php");
evtSource.onmessage = function(e) {
console.log(e.data);
};
使用第三方推送服务
Firebase Cloud Messaging (FCM) 是流行的推送解决方案。
发送 FCM 通知:
function sendFCM($token, $title, $body) {
$url = 'https://fcm.googleapis.com/fcm/send';
$serverKey = 'YOUR_SERVER_KEY';
$notification = [
'title' => $title,
'body' => $body,
'icon' => 'icon',
'sound' => 'default'
];
$fields = [
'to' => $token,
'notification' => $notification,
'priority' => 'high'
];
$headers = [
'Authorization: key=' . $serverKey,
'Content-Type: application/json'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
使用 AJAX 长轮询
长轮询是传统轮询的改进版本,服务器在有数据时才响应。
服务端实现:

// wait.php
$data = getNewData(); // 自定义获取新数据函数
while (empty($data)) {
usleep(100000); // 100ms
$data = getNewData();
if (connection_aborted()) {
exit;
}
}
echo json_encode($data);
客户端实现:
function longPoll() {
fetch('wait.php')
.then(response => response.json())
.then(data => {
console.log(data);
longPoll();
});
}
longPoll();
使用消息队列
对于高并发场景,可以使用 RabbitMQ 等消息队列。
安装 PHP AMQP 扩展:
pecl install amqp
发送消息示例:
$connection = new AMQPConnection([
'host' => 'localhost',
'port' => 5672,
'login' => 'guest',
'password' => 'guest'
]);
$connection->connect();
$channel = new AMQPChannel($connection);
$exchange = new AMQPExchange($channel);
$exchange->setName('notifications');
$exchange->setType(AMQP_EX_TYPE_FANOUT);
$exchange->declareExchange();
$exchange->publish(json_encode(['message' => 'Hello']), '');
接收消息示例:
$queue = new AMQPQueue($channel);
$queue->setName('notification_queue');
$queue->declareQueue();
$queue->bind('notifications', '');
$queue->consume(function($envelope, $queue) {
$message = json_decode($envelope->getBody(), true);
// 处理消息
$queue->ack($envelope->getDeliveryTag());
});
每种方法适用于不同场景:WebSocket 适合实时双向通信,SSE 适合服务器到客户端的单向推送,FCM 适合移动端推送,长轮询适合简单实现,消息队列适合高并发分布式系统。根据具体需求选择最合适的方案。






