php 实现长连接
PHP 实现长连接的方法
在 PHP 中实现长连接通常涉及保持客户端与服务器之间的持久连接,避免频繁的建立和断开连接。以下是几种常见的方法:
使用 HTTP 长轮询(Long Polling)
HTTP 长轮询是一种模拟长连接的技术,客户端发送请求后,服务器保持连接开放,直到有新数据或超时才返回响应。
// 服务器端代码示例
while (true) {
$data = getDataFromSource(); // 获取数据
if ($data) {
echo json_encode($data);
break;
}
usleep(100000); // 休眠 100ms 以减少 CPU 占用
// 设置超时时间(如 30 秒)
if (time() - $startTime > 30) {
echo json_encode(['status' => 'timeout']);
break;
}
}
客户端通过 AJAX 请求服务器,服务器在有数据或超时时返回响应,客户端收到响应后立即发起新的请求。
使用 WebSocket
WebSocket 是真正的长连接协议,适合实时通信场景。PHP 可以通过 Ratchet 等库实现 WebSocket 服务器。
// 安装 Ratchet
composer require cboden/ratchet
// WebSocket 服务器示例
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class MyWebSocket implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
// 新连接逻辑
}
public function onMessage(ConnectionInterface $conn, $msg) {
// 处理消息
}
public function onClose(ConnectionInterface $conn) {
// 连接关闭逻辑
}
public function onError(ConnectionInterface $conn, \Exception $e) {
// 错误处理
}
}
$server = new \Ratchet\App('localhost', 8080);
$server->route('/ws', new MyWebSocket());
$server->run();
客户端通过 JavaScript 的 WebSocket API 连接服务器:
const socket = new WebSocket('ws://localhost:8080/ws');
socket.onmessage = (event) => {
console.log('Received:', event.data);
};
使用 Swoole 扩展
Swoole 是一个高性能的 PHP 协程框架,支持长连接和异步 IO。
// 安装 Swoole
pecl install swoole
// Swoole HTTP 服务器示例
$server = new Swoole\Http\Server('0.0.0.0', 9501);
$server->on('Request', function ($request, $response) {
$response->header('Content-Type', 'text/plain');
$response->end('Hello World');
});
$server->start();
Swoole 还支持 WebSocket 和 TCP/UDP 长连接,适合高并发场景。
数据库长连接
PHP 的数据库连接可以通过 pconnect 实现持久连接,避免重复建立连接的开销。
// MySQL 持久连接
$db = new PDO(
'mysql:host=localhost;dbname=test',
'username',
'password',
[PDO::ATTR_PERSISTENT => true]
);
注意:数据库长连接可能导致连接数过多,需结合连接池管理。
注意事项
- 资源占用:长连接会占用服务器资源,需合理设置超时和连接数限制。
- 兼容性:WebSocket 和 Swoole 需要服务器支持,传统 CGI 模式可能无法直接使用。
- 心跳机制:长连接需实现心跳检测,避免僵尸连接。
以上方法可根据实际需求选择,WebSocket 和 Swoole 适合实时通信,HTTP 长轮询兼容性更好,数据库长连接适合高频数据库操作场景。







