当前位置:首页 > 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);
}

心跳机制实现

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

php socket实现长连接

// 服务器端心跳检测
$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 可以实现多进程处理多个连接:

php socket实现长连接

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);
});

性能优化建议

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

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

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

标签: phpsocket
分享给朋友:

相关文章

php实现打印功能

php实现打印功能

PHP实现打印功能的方法 在PHP中实现打印功能可以通过多种方式完成,包括直接输出到浏览器、生成PDF文件、调用打印机接口等。以下是几种常见的方法: 直接输出HTML内容 PHP可以通过echo或p…

php长连接实现

php长连接实现

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

php购物车实现

php购物车实现

PHP购物车实现方法 使用PHP实现购物车功能可以通过多种方式完成,以下是几种常见的实现方法: Session存储购物车数据 利用PHP的$_SESSION超全局变量存储购物车数据是最简单的方法。用…

php实现推送

php实现推送

PHP 实现推送功能的方法 PHP 实现推送功能可以通过多种方式完成,包括 WebSocket、Server-Sent Events (SSE)、长轮询或第三方推送服务。以下是几种常见的方法: 使用…

php实现的分页

php实现的分页

PHP 实现分页的方法 基本分页逻辑 分页的核心在于计算总页数、当前页码以及数据偏移量。假设每页显示 10 条数据: $current_page = isset($_GET['page']) ? (…

php 实现单链表

php 实现单链表

单链表的基本概念 单链表是一种线性数据结构,由节点组成,每个节点包含数据域和指向下一个节点的指针域。链表的头节点是访问整个链表的入口。 单链表的节点类实现 在PHP中,可以通过类来定义链表节…