当前位置:首页 > PHP

php socket实现长连接

2026-01-28 22:49:53PHP

PHP Socket 实现长连接的方法

使用 stream_socket_server 创建服务器端

在 PHP 中可以通过 stream_socket_server 创建一个 TCP 服务器。以下是一个简单的服务器端实现:

$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!$socket) {
    die("$errstr ($errno)");
}

while (true) {
    $conn = stream_socket_accept($socket, -1);
    if ($conn) {
        while (true) {
            $data = fread($conn, 1024);
            if (!$data) break;
            echo "Received: $data";
            fwrite($conn, "Server response: $data");
        }
        fclose($conn);
    }
}

客户端保持长连接

客户端可以使用 stream_socket_client 建立连接并保持长连接:

$socket = stream_socket_client("tcp://127.0.0.1:8000", $errno, $errstr, 30);
if (!$socket) {
    die("$errstr ($errno)");
}

stream_set_blocking($socket, 0);
stream_set_timeout($socket, 0);

while (true) {
    fwrite($socket, "Hello Server\n");
    $data = fread($socket, 1024);
    if ($data) {
        echo "Received: $data";
    }
    sleep(1);
}

心跳机制实现

为了维持长连接,通常需要实现心跳机制:

// 服务器端心跳检测
$lastActive = time();
while (true) {
    $data = fread($conn, 1024);
    if ($data) {
        $lastActive = time();
        // 处理数据
    } elseif (time() - $lastActive > 30) {
        // 超时断开
        fclose($conn);
        break;
    }
}

非阻塞模式设置

设置非阻塞模式可以避免连接阻塞:

stream_set_blocking($socket, 0);

多进程处理连接

使用 pcntl_fork 可以实现多进程处理多个连接:

while (true) {
    $conn = stream_socket_accept($socket, -1);
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('Could not fork');
    } elseif ($pid) {
        // 父进程
        continue;
    } else {
        // 子进程处理连接
        handleConnection($conn);
        exit;
    }
}

使用 socket_select 处理多连接

更高效的方式是使用 socket_select 处理多个连接:

$read = [$socket];
$write = $except = null;

while (true) {
    $changed = $read;
    if (socket_select($changed, $write, $except, 0) > 0) {
        foreach ($changed as $sock) {
            if ($sock === $socket) {
                $conn = stream_socket_accept($socket);
                $read[] = $conn;
            } else {
                $data = fread($sock, 1024);
                if (!$data) {
                    fclose($sock);
                    unset($read[array_search($sock, $read)]);
                }
                // 处理数据
            }
        }
    }
}

错误处理和资源释放

确保正确处理错误和释放资源:

register_shutdown_function(function() use ($socket) {
    fclose($socket);
});

性能优化建议

对于高性能场景,建议考虑以下优化:

php socket实现长连接

  • 使用 libevent 或 ev 扩展
  • 考虑使用 Swoole 等高性能 PHP 网络框架
  • 适当调整缓冲区大小
  • 实现连接池管理

以上方法提供了在 PHP 中实现 Socket 长连接的基本框架,可以根据实际需求进行调整和扩展。

标签: phpsocket
分享给朋友:

相关文章

php实现搜索功能

php实现搜索功能

实现基本的搜索功能 在PHP中实现搜索功能通常涉及数据库查询。以下是一个简单的实现方式,假设使用MySQL数据库: <?php // 连接数据库 $conn = new mysqli('loc…

php 实现验证码

php 实现验证码

使用 PHP 生成验证码 验证码(CAPTCHA)用于防止自动化脚本提交表单,以下是几种常见的 PHP 实现方法。 使用 GD 库生成图片验证码 GD 库是 PHP 的图像处理扩展,可用于生成验证码…

php 实现单点登录

php 实现单点登录

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

php 无限分类的实现

php 无限分类的实现

无限分类的实现方法 无限分类通常用于构建树形结构数据,如商品分类、多级菜单等。以下是几种常见的实现方式: 邻接列表模型(Adjacency List) 邻接列表是最简单的实现方式,通过在每个节点中存…

php 实现面包屑导航

php 实现面包屑导航

实现面包屑导航的方法 面包屑导航(Breadcrumb Navigation)是一种常见的网站导航方式,用于显示用户当前页面的路径。以下是几种在 PHP 中实现面包屑导航的方法。 基于 URL 路径…

php数据库实现

php数据库实现

PHP 连接 MySQL 数据库 使用 mysqli 扩展连接 MySQL 数据库: <?php $servername = "localhost"; $username = "usernam…