php 子进程监听消息,swoole学习笔记之多线程端口监听问题记录 多进程epoll模式...
发布日期:2025-05-03 00:03:34 浏览次数:12 分类:精选文章

本文共 3411 字,大约阅读时间需要 11 分钟。

epoll模式主要是直接对socket进行监听,无需轮询,当socket状态发生变化时会自动触发相应的事件处理。这意味着 epoll 模式能够高效地管理网络连接,减少资源消耗。

以下是关于epoll模式和Worker类的实现细节:

  • Worker类的基本结构

    Worker类是一个用于管理socket监听和处理连接的类,主要包含以下属性和方法:

    • 属性

      • socket:用于存储当前socket资源。
      • onConnect:连接建立时的回调函数。
      • reusePort:是否允许端口复用。
      • workerNum:子进程的数量。
      • allSocket:存储所有socket资源。
      • addr:监听地址和端口。
    • 方法

      • __construct($socket_address):初始化socket地址和端口。
      • start():启动socket监听。
      • fork():创建子进程,处理客户端连接。
      • accept():设置socket选项和监听端口。
      • onConnectonMessage:连接建立和消息接收的回调函数。
  • socket监听与事件处理

    accept()方法中,我们设置socket选项,允许端口复用并开启多端口监听。通过stream_socket_server创建socket资源,并使用swoole_event_add添加事件处理函数。

  • 子进程管理

    fork()方法用于创建子进程,处理客户端连接。每个子进程负责接收客户端请求,并在连接建立时触发onConnect回调函数。

  • 资源管理

    accept()方法中,我们创建资源流上下文,并设置socket选项。通过stream_context_set_option设置端口复用和地址复用选项,确保多进程环境下的负载均衡。

  • 事件处理

    当socket检测到可读事件时,触发相应的回调函数。onConnect回调函数处理连接建立事件,而onMessage回调函数处理消息接收事件。

  • 消息处理

    onMessage回调函数中,读取客户端数据并响应。通过fread读取数据,判断是否为有效资源,若数据为空则关闭socket。

  • 以下是Worker类的核心实现代码示例:

    class Worker {    protected $socket = NULL;    public $onConnect = NULL;    public $reusePort = 1;    public $workerNum = 2;    public $allSocket;    public $addr;    public function __construct($socket_address) {        $this->addr = $socket_address;    }    public function start() {        $this->fork();    }    public function fork() {        for ($i = 0; $i < $this->workerNum; $i++) {            $pid = pcntl_fork();            if ($pid < 0) {                exit("创建失败");            } elseif ($pid > 0) {                // 父进程处理子进程            } else {                echo "zi";                $this->accept();                exit;            }        }    }    public function accept() {        $opts = array(            "socket" => array(                "backlog" => 10240,            ),        );        $context = stream_context_create($opts);        stream_context_set_option($context, "socket", "so_reuseport", 1);        stream_context_set_option($context, "socket", "so_reuseaddr", 1);        $this->socket = stream_socket_server($this->addr, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context);        swoole_event_add($this->socket, function ($fd) {            $clientSocket = stream_socket_accept($fd);            if (!empty($clientSocket) && is_callable($this->onConnect)) {                echo "连接事件触发", (int)$clientSocket, PHP_EOL;                call_user_func($this->onConnect, $clientSocket);            }        });        swoole_event_add($clientSocket, function ($fd) {            $buffer = fread($fd, 1024);            if (empty($buffer)) {                if (!is_resource($fd) || feof($fd)) {                    fclose($fd);                }            }            if (!empty($buffer) && is_callable($this->onMessage)) {                call_user_func($this->onMessage, $fd, $buffer);            }        });    }}

    以下是使用示例:

    $worker = new Worker("tcp://0.0.0.0:9801");$worker->reusePort = true;$worker->onConnect = function ($fd) {    echo "连接事件触发", (int)$fd, PHP_EOL;};$worker->onMessage = function ($conn, $message) {    var_dump("123");    $content = "123123123";    $http_resonse = "HTTP/1.1 200 OK";    $http_resonse .= "Content-Type: text/html;charset=UTF-8";    $http_resonse .= "Connection: keep-alive";    $http_resonse .= "Server: php socket server";    $http_resonse .= "Content-length: " . strlen($content);    $http_resonse .= $content;    fwrite($conn, $http_resonse);};$worker->start();

    通过上述实现,我们可以高效地管理网络连接,处理大量客户端请求。epoll模式的异步特性使得该实现能够在高负载环境下保持稳定性能。

    上一篇:PHP 学习笔记 (四)
    下一篇:php 大文件上传

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2026年06月17日 05时10分59秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章