账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    PHP Ev 事件扩展如何监听嵌套的事件??
    32
    0

    Linux 使用 PHP Ev 扩展,监听 socket

    这边有两个递进的监听:

    1. 监听客户端连接
    2. 客户端连接后,监听客户端进行收发数据

    具体实现代码如下:

    <?php
    
    
    $tcp    = "127.0.0.1:9005";
    $count  = 2;
    $pids   = [];
    
    // 端口多进程监听
    for ($i = 0; $i < $count; ++$i)
    {
        $pid = pcntl_fork();
    
        if ($pid < 0) {
            exit('生成子进程失败\n');
        } else if ($pid > 0) {
            // 父进程
            $pids[] = $pid;
        } else {
            var_dump("产生子进程 {$i}");
    
            // 创建资源流上下文
            $context = stream_context_create([
                'socket' => [
                    //
                    'backlog' => 102400
                ]
            ]);
    
            // 设置端口重用
            stream_context_set_option($context , 'socket' , 'so_reuseport' , 1);
    
            // 监听客户端链接 + 设置端口重用
            $server = stream_socket_server($tcp , $errno , $errstr , STREAM_SERVER_BIND | STREAM_SERVER_LISTEN , $context);
            $clients = [];
    
            // 如果资源可读,读取,并且一直监听
            $ev = new EvIo($server , Ev::READ , function($watcher) use($clients , $server){
    
                var_dump("接收到客户端链接");
                var_dump($watcher->fd === $server);
    
                // $client     = stream_socket_accept($watcher->fd);
                $client     = stream_socket_accept($server);
                $clients[]  = $client;
    
                // 设置资源阻塞模式
                stream_set_blocking($client , false);
    
                // 事件监听
                $ev = new EvIO($client , Ev::READ | Ev::WRITE , function($watcher) use($client , $clients){
                    var_dump($watcher->fd === $client);
    
                    var_dump("客户端资源可读!!");
                });
    
                var_dump("监听客户端数据收发已经就绪");
            });
    
            // 开始事件监听!
            Ev::run();
    
            // 不要进入父进程领域
            exit;
        }
    }
    
    foreach ($pids as $v)
    {
        pcntl_waitpid($v , $status , WUNTRACED);
    }
    
    var_dump("所有进程都已经退出");

    运行后发现,如果有客户端连接,则触发回调函数,但是,如果该客户端发送了数据到服务器,却没有触发回调。

    不知道该如何破解??

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 几人难应 普通会员 1楼

      在PHP Ev扩展中,可以使用listen函数来监听嵌套的事件。listen函数接受两个参数:事件的名称和事件监听器的函数。

      以下是一个简单的例子,展示了如何在PHP Ev扩展中监听嵌套的事件:

      ```php

      listen('child', function ($childEvent) { echo "Child event triggered: " . $childEvent->getEventName(); }); // 添加一个事件监听器 $event->listen('parent', function ($parentEvent) { echo "Parent event triggered: " . $parentEvent->getEventName(); }); // 启动事件监听器 $event->start(); ?>

      ```

      在这个例子中,我们首先创建了一个事件,并添加了一个事件监听器。然后,我们添加了一个事件监听器,该监听器会触发子事件,并输出子事件的名称。

      请注意,listen函数在多线程环境中工作,因此在运行此代码时,你应该确保所有的事件监听器都在同一线程中运行。否则,可能会出现错误。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部