当前位置:首页 > PHP

php socket实现长连接

2026-02-13 20:58:18PHP

PHP Socket 实现长连接的方法

长连接(Keep-Alive)的核心在于维持客户端与服务器之间的持久通信通道,避免频繁建立和断开连接。以下是实现长连接的几种方法:

使用 stream_socket_serverstream_socket_accept

创建一个基本的 Socket 服务器并保持连接:

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

while (true) {
    $client = stream_socket_accept($socket, -1);
    if ($client) {
        while (true) {
            $data = fread($client, 1024);
            if ($data === false || $data === '') {
                break;
            }
            fwrite($client, "Received: " . $data);
        }
        fclose($client);
    }
}

使用 socket_createsocket_accept

通过 PHP 的 socket_* 函数实现更底层的长连接:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8000);
socket_listen($socket);

while (true) {
    $client = socket_accept($socket);
    if ($client) {
        while (true) {
            $data = socket_read($client, 1024);
            if ($data === false || $data === '') {
                break;
            }
            socket_write($client, "Received: " . $data);
        }
        socket_close($client);
    }
}

设置超时和心跳机制

为了避免连接因长时间无数据而断开,可以设置心跳包:

$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
stream_set_timeout($socket, 0); // 非阻塞模式

while (true) {
    $client = stream_socket_accept($socket);
    if ($client) {
        stream_set_timeout($client, 3600); // 超时时间为 1 小时
        while (true) {
            $data = fread($client, 1024);
            if ($data === false || $data === '') {
                break;
            }
            if (trim($data) === 'PING') {
                fwrite($client, 'PONG');
            } else {
                fwrite($client, "Received: " . $data);
            }
        }
        fclose($client);
    }
}

使用多进程或异步处理

对于高并发场景,可以使用 pcntl_forklibevent 实现异步处理:

php socket实现长连接

$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);

while (true) {
    $client = stream_socket_accept($socket);
    if ($client) {
        $pid = pcntl_fork();
        if ($pid == -1) {
            die('Could not fork');
        } elseif ($pid) {
            // Parent process
            continue;
        } else {
            // Child process
            while (true) {
                $data = fread($client, 1024);
                if ($data === false || $data === '') {
                    break;
                }
                fwrite($client, "Received: " . $data);
            }
            fclose($client);
            exit();
        }
    }
}

注意事项

  • 资源管理:长连接会占用服务器资源,需合理设置超时和心跳机制。
  • 错误处理:确保在连接异常时能正确关闭 Socket。
  • 性能优化:高并发场景建议结合异步 I/O 或多进程技术。

通过以上方法,可以在 PHP 中实现稳定的长连接通信。

标签: phpsocket
分享给朋友:

相关文章

php实现排序

php实现排序

PHP 数组排序方法 PHP 提供了多种内置函数用于数组排序,适用于不同的排序需求。以下是常见的排序方法: 按值升序排序 sort() 函数对数组按值升序排序,重置键名(索引数组适用): $num…

php实现异步

php实现异步

PHP 实现异步的方法 PHP 本身是同步执行的脚本语言,但可以通过以下方法模拟异步操作或实现异步效果: 使用多进程(pcntl_fork) 通过 pcntl_fork 创建子进程实现异步,适用于…

php 函数实现

php 函数实现

PHP 函数实现基础 PHP 函数的定义使用 function 关键字,后跟函数名和参数列表。函数名不区分大小写,但建议保持一致。 function functionName($param1, $p…

php 实现类

php 实现类

PHP 类的基本实现 在 PHP 中,类通过 class 关键字定义,后跟类名和一对花括号。类名通常遵循大驼峰命名法(如 ClassName)。以下是基本语法: class ClassName {…

php实现https

php实现https

PHP 实现 HTTPS 请求 在 PHP 中实现 HTTPS 请求,可以通过多种方式完成,包括使用内置函数、cURL 扩展或第三方库。以下是几种常见的方法: 使用 file_get_content…

php redis 队列实现

php redis 队列实现

PHP Redis 队列实现 Redis 是一个高性能的键值存储系统,常被用作消息队列。以下是使用 PHP 和 Redis 实现队列的几种方法。 安装依赖 确保已安装 PHP Redis 扩展。可以…