当前位置:首页 > 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 实现长轮询

<?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和MySQL实现基础的搜索功能需要结合表单提交与数据库查询。创建一个HTML表单用于接收用户输入的搜索关键词,通过PHP处理表单数据并查询数据库。 // 搜索表单 (HT…

php长连接实现

php长连接实现

PHP 长连接实现方法 长连接(Keep-Alive)允许客户端与服务器在一次TCP连接中发送和接收多个HTTP请求/响应,减少重复建立连接的开销。以下是PHP中实现长连接的几种方式: 配置HTTP…

php验证码的实现

php验证码的实现

PHP 验证码实现方法 使用 GD 库生成基础验证码 创建画布并生成随机字符串作为验证码内容: session_start(); $width = 120; $height = 40; $image…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php 实现单点登录

php 实现单点登录

PHP 实现单点登录的方法 单点登录(SSO)允许用户通过一次登录访问多个相互信任的系统。以下是基于 PHP 的实现方案: 基于共享 Session 的方案 在同一个主域名下的子域名间可以通过共享…

无限分类实现 php

无限分类实现 php

无限分类的实现方法 无限分类通常用于构建多层级结构的数据,如商品分类、部门架构等。以下是几种常见的实现方式: 邻接列表模式(Adjacency List) 邻接列表是最简单的实现方式,通过在每个记录…