php实现推送功能
PHP 实现推送功能的方法
推送功能通常分为两种类型:服务器推送(Server-Sent Events, SSE)和WebSocket 推送。以下是几种常见的 PHP 实现推送功能的方法:
使用 Server-Sent Events (SSE)
SSE 是一种基于 HTTP 的单向推送技术,适用于服务器向客户端推送实时数据。
// SSE 服务器端代码示例
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
$data = json_encode(['time' => date('H:i:s')]);
echo "data: {$data}\n\n";
ob_flush();
flush();
sleep(1);
}
客户端 JavaScript 代码:
const eventSource = new EventSource('sse.php');
eventSource.onmessage = function(e) {
console.log(e.data);
};
特点:
- 基于 HTTP,无需额外协议。
- 单向通信(服务器到客户端)。
- 自动重连机制。
使用 WebSocket
WebSocket 提供全双工通信,适合需要双向交互的场景。PHP 可以通过库(如 Ratchet)实现 WebSocket 服务。
安装 Ratchet:
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();
Chat 类实现:
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($client !== $from) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
echo "Connection closed: {$conn->resourceId}\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
客户端 JavaScript 代码:
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = function(e) {
console.log(e.data);
};
特点:
- 全双工通信。
- 低延迟,适合高频交互场景。
- 需要额外服务端支持。
使用第三方推送服务
对于移动端或大规模推送,可以集成第三方服务(如 Firebase Cloud Messaging, FCM)。
PHP 调用 FCM 示例:
$url = 'https://fcm.googleapis.com/fcm/send';
$apiKey = 'YOUR_SERVER_KEY';
$data = [
'to' => '/topics/all',
'notification' => [
'title' => 'New Message',
'body' => 'Hello from PHP!'
]
];
$options = [
'http' => [
'header' => "Authorization: key={$apiKey}\r\nContent-Type: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
echo $result;
特点:
- 适用于移动端推送。
- 无需维护长连接。
- 依赖第三方服务。
使用长轮询(Long Polling)
长轮询是传统轮询的改进版,客户端发送请求后,服务器保持连接直到有新数据。
PHP 长轮询示例:
$lastEventId = $_SERVER['HTTP_LAST_EVENT_ID'] ?? 0;
while (true) {
$newData = checkForNewData($lastEventId);
if ($newData) {
echo json_encode($newData);
break;
}
sleep(1);
}
客户端 JavaScript 代码:
function longPoll() {
fetch('poll.php')
.then(response => response.json())
.then(data => {
console.log(data);
longPoll();
});
}
longPoll();
特点:

- 兼容性高,无需特殊协议。
- 比传统轮询更高效。
- 仍有一定延迟。
选择建议
- SSE:适合简单服务器到客户端的单向推送(如通知、实时日志)。
- WebSocket:适合双向交互场景(如聊天室、游戏)。
- 第三方服务:适合移动端或无需自建推送服务的场景。
- 长轮询:兼容性要求高且推送频率低的场景。






