当前位置:首页 > PHP

php 实现长轮询

2026-02-13 16:47:29PHP

PHP 实现长轮询的方法

长轮询(Long Polling)是一种服务器推送技术,客户端向服务器发送请求后,服务器保持连接开放,直到有数据可发送或超时。以下是实现长轮询的步骤和代码示例。

服务器端代码

创建一个 PHP 脚本(如 long_polling.php)处理长轮询请求。该脚本会检查数据更新,并在有更新或超时时返回响应。

<?php
// 设置脚本执行时间不受限制
set_time_limit(0);

// 模拟数据存储(实际应用中可能使用数据库或缓存)
$lastUpdate = isset($_GET['lastUpdate']) ? (int)$_GET['lastUpdate'] : 0;

// 长轮询超时时间(秒)
$timeout = 30;
$startTime = time();

// 检查数据是否更新
while (true) {
    // 模拟数据更新(实际应用中根据业务逻辑判断)
    $currentUpdate = filemtime('data.txt'); // 假设通过文件修改时间判断更新

    if ($currentUpdate > $lastUpdate) {
        // 返回新数据
        $response = [
            'status' => 'success',
            'data' => file_get_contents('data.txt'),
            'lastUpdate' => $currentUpdate
        ];
        echo json_encode($response);
        break;
    }

    // 检查是否超时
    if (time() - $startTime >= $timeout) {
        $response = ['status' => 'timeout'];
        echo json_encode($response);
        break;
    }

    // 减少 CPU 占用
    usleep(100000); // 0.1 秒
}
?>

客户端代码

使用 JavaScript 发起长轮询请求,并在收到响应后处理数据或重新发起请求。

function longPolling(lastUpdate = 0) {
    fetch(`long_polling.php?lastUpdate=${lastUpdate}`)
        .then(response => response.json())
        .then(data => {
            if (data.status === 'success') {
                console.log('New data:', data.data);
                // 处理新数据后继续轮询
                longPolling(data.lastUpdate);
            } else if (data.status === 'timeout') {
                // 超时后重新发起轮询
                longPolling(lastUpdate);
            }
        })
        .catch(error => {
            console.error('Polling error:', error);
            // 错误后重新发起轮询
            setTimeout(() => longPolling(lastUpdate), 1000);
        });
}

// 启动长轮询
longPolling();

实际应用优化

  • 数据存储:替换文件操作为数据库或缓存(如 Redis),通过查询判断数据更新。
  • 性能优化:避免频繁查询数据库,可以使用缓存或消息队列。
  • 错误处理:增加客户端重试机制和服务器端日志记录。
  • 安全性:验证客户端请求,防止恶意攻击。

示例:数据库实现

假设使用 MySQL 存储数据,通过检查 last_modified 字段判断更新:

<?php
set_time_limit(0);
$lastUpdate = isset($_GET['lastUpdate']) ? (int)$_GET['lastUpdate'] : 0;
$timeout = 30;
$startTime = time();

// 数据库连接
$db = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');

while (true) {
    $stmt = $db->prepare("SELECT * FROM messages WHERE last_modified > ? LIMIT 1");
    $stmt->execute([$lastUpdate]);
    $data = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($data) {
        echo json_encode([
            'status' => 'success',
            'data' => $data['content'],
            'lastUpdate' => $data['last_modified']
        ]);
        break;
    }

    if (time() - $startTime >= $timeout) {
        echo json_encode(['status' => 'timeout']);
        break;
    }

    usleep(100000);
}
?>

通过以上方法,可以实现高效的长轮询机制,适用于实时性要求较高的应用场景。

php 实现长轮询

标签: php长轮询
分享给朋友:

相关文章

php实现购物车

php实现购物车

PHP实现购物车功能 购物车功能是电商网站的核心模块之一,通常涉及商品添加、删除、数量修改和结算等操作。以下是使用PHP实现购物车功能的几种方法。 使用Session存储购物车数据 Session是…

php实现验证码

php实现验证码

PHP实现验证码的方法 使用GD库生成验证码 GD库是PHP中处理图像的扩展,可用于生成验证码图片。 <?php session_start(); $width = 120; $height…

php实现图片上传

php实现图片上传

实现图片上传的基本步骤 创建HTML表单用于文件上传,表单需设置enctype="multipart/form-data"属性,确保文件数据正确传输。 <form action="uploa…

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE…

php验证码实现

php验证码实现

验证码实现方法 在PHP中实现验证码功能通常涉及生成随机字符串或数字,将其转换为图像,并通过会话(Session)进行验证。以下是几种常见的实现方式: 使用GD库生成图像验证码 GD库是PHP内置的…

php 实现登录

php 实现登录

PHP 登录功能实现 使用 PHP 实现登录功能通常需要结合数据库验证和会话管理。以下是一个基本的登录实现流程: 数据库准备 创建用户表存储用户名和密码(建议使用哈希加密): CREATE T…