博客
关于我
php 子进程监听消息,swoole学习笔记之多线程端口监听问题记录 多进程epoll模式...
阅读量:793 次
发布时间:2023-02-28

本文共 3483 字,大约阅读时间需要 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模式的异步特性使得该实现能够在高负载环境下保持稳定性能。

    转载地址:http://egvfk.baihongyu.com/

    你可能感兴趣的文章
    PageHelper:上手教程(最详细)
    查看>>
    PageOffice如何实现从零开始动态生成图文并茂的Word文档
    查看>>
    PageRank算法
    查看>>
    Paint类(画笔)
    查看>>
    paip.android 手机输入法制造大法
    查看>>
    paip.spring3 mvc servlet的配置以及使用最佳实践
    查看>>
    Palindrome Number leetcode java
    查看>>
    Palo Alto Networks Expedition 未授权SQL注入漏洞复现(CVE-2024-9465)
    查看>>
    Palo Alto Networks PAN-OS身份认证绕过导致RCE漏洞复现(CVE-2024-0012)
    查看>>
    Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现
    查看>>
    Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现
    查看>>
    Panalog 日志审计系统 sprog_upstatus.php SQL 注入漏洞复现(XVE-2024-5232)
    查看>>
    PANDA VALUE_COUNTS包含GROUP BY之前的所有值
    查看>>
    pandas -按连续日期时间段分组
    查看>>
    pandas :to_excel() float_format
    查看>>
    pandas :将多列汇总为一列,没有最后一列
    查看>>
    pandas :将时间戳转换为 datetime.date
    查看>>
    pandas :将行取消堆叠到新列中
    查看>>
    pandas DataFrame 中的自定义浮点格式
    查看>>
    Pandas DataFrame 的 describe()方法详解-ChatGPT4o作答
    查看>>