为了账号安全,请及时绑定邮箱和手机立即绑定

PHP Ev 事件扩展如何监听嵌套的事件??

PHP Ev 事件扩展如何监听嵌套的事件??

PHP
牧羊人nacy 2019-03-18 15:35:02
Linux 使用 PHP Ev 扩展,监听 socket。 这边有两个递进的监听: 监听客户端连接 客户端连接后,监听客户端进行收发数据 具体实现代码如下: <?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("所有进程都已经退出"); 运行后发现,如果有客户端连接,则触发回调函数,但是,如果该客户端发送了数据到服务器,却没有触发回调。 不知道该如何破解??
查看完整描述

1 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

EvIo 有些特性:

  • 同作用域下,同类事件会相互覆盖,后面定义的覆盖前面的
  • 嵌套事件,需要再次执行 Ev::run 才会触发,再次调用 Ev::run 后事件的执行不可预测。

基于上面两个,我发现了一个特殊的现象:

function login($fd , $flag , $callback , $args){
    return new EvIo($fd , $flag , $callback , $args);
}

// 这种方式定义多个重复事件,都会触发 ..
// 无语,但是目前就是用这种方式投入使用的
$one = login($socket , Ev::READ , null , null);
$two = login($socket , Ev::READ , null , null);

// 跑进程
Ev::run();
查看完整回答
反对 回复 2019-03-18
  • 1 回答
  • 0 关注
  • 336 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信