
本文介绍如何用 websocket 技术替代高频 http 轮询(如 setinterval),在 php 后端与 javascript 前端之间建立低延迟、高效率的双向实时通信,显著降低服务器压力并提升响应及时性。
本文介绍如何用 websocket 技术替代高频 http 轮询(如 setinterval),在 php 后端与 javascript 前端之间建立低延迟、高效率的双向实时通信,显著降低服务器压力并提升响应及时性。
传统基于 setInterval() 的轮询(例如每秒发起一次 fetch() 请求)看似简单,实则存在严重缺陷:大量空响应浪费带宽与 CPU 资源;请求堆积导致延迟不可控;服务端并发压力陡增;无法实现真正的“有变更即推送”。更优解是采用 WebSocket 协议——它在客户端与服务端之间建立持久化、全双工的 TCP 连接,使服务端可在数据就绪时主动推送更新,彻底消除无效请求。
✅ 推荐方案:PHP WebSocket 服务 + 浏览器原生 WebSocket
PHP 本身不内置 WebSocket 服务器,但可通过轻量级库快速搭建。推荐使用 Ratchet(基于 ReactPHP),它稳定、文档完善且兼容主流环境。
1. 安装与基础服务端(PHP)
composer require cboden/ratchet
创建 server.php:
<?php use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
class IpUpdateHandler implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage();
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
// 可选:处理客户端发来的指令(如订阅特定 IP 状态)
// $this->broadcast("Received: {$msg}");
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} closed\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error for {$conn->resourceId}: {$e->getMessage()}\n";
$conn->close();
}
// 公共方法:供业务逻辑调用,向所有客户端广播 IP 更新
public function broadcastIpUpdate(string $ip, string $status) {
$data = json_encode(['type' => 'ip_update', 'ip' => $ip, 'status' => $status, 'timestamp' => date('c')]);
foreach ($this->clients as $client) {
if ($client->resourceId && $client->isConnected()) {
$client->send($data);
}
}
}
}
// 启动服务(监听 8080 端口)
$handler = new IpUpdateHandler();
$server = IoServer::factory(
new HttpServer(new WsServer($handler)),
8080
);
// 示例:模拟后端检测到 IP 状态变更后主动推送
// (实际中可集成到你的 IP 监控逻辑、数据库触发器或消息队列消费者中)
$loop = \React\EventLoop\Factory::create();
$loop->addPeriodicTimer(5, function () use ($handler) {
// 模拟每 5 秒随机推送一个 IP 状态更新
$ips = ['192.168.1.10', '203.0.113.42', '10.0.0.5'];
$statuses = ['online', 'offline', 'blocked'];
$ip = $ips[array_rand($ips)];
$status = $statuses[array_rand($statuses)];
$handler->broadcastIpUpdate($ip, $status);
});
$loop->run();
2. 前端 JavaScript 连接与监听
// 建立 WebSocket 连接(注意:需与服务端协议、端口一致)
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => {
console.log('WebSocket connected');
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'ip_update') {
console.log(`IP ${data.ip} is now ${data.status}`);
// ✅ 此处更新 UI,无需轮询!
document.getElementById('ip-status').textContent =
`IP: ${data.ip} — Status: ${data.status}`;
}
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
socket.onclose = () => {
console.warn('WebSocket disconnected — consider auto-reconnect logic');
};
⚠️ 关键注意事项
- 部署与代理:生产环境需通过 Nginx 或 Apache 配置 WebSocket 代理(启用 Upgrade 和 Connection 头),并确保防火墙放行对应端口。
- 连接管理:务必实现前端重连机制(指数退避)、服务端心跳检测(onPing/onPong),避免长连接意外中断。
- 安全性:验证 Origin、使用 wss://(TLS 加密)、对敏感操作添加身份认证(如 Token 握手鉴权)。
- 扩展性:单机 Ratchet 适合中小规模;高并发场景建议接入 Redis Pub/Sub 实现多进程/多服务器广播,或选用 Swoole(原生协程 WebSocket 服务器,性能更优)。
✅ 总结
用 WebSocket 替代定时轮询,不是简单的“换一种请求方式”,而是架构思维的升级:从「客户端盲目索取」转向「服务端智能推送」。它让您的 PHP API 真正具备实时性、可扩展性与工业级健壮性。立即弃用 setInterval(fetch(...)),拥抱持久连接——每一次推送,都更精准、更低耗、更及时。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











