当前位置: 首页 > 后端技术 > PHP

PHPsocket初探---硬着头皮继续libevent(二)

时间:2023-03-29 17:51:52 PHP

【原地址:https://blog.ti-node.com/blog...】其实还有个事件扩展onphp.net的说明手册,但是对于初学者来说用处不大,因为没有很多强大的用例代码,也没有强大的UserContributedNotes,所以可能的结果是:完全看不懂.这是活动文档,点这里,大家感受一下。从文档来看,事件扩展实现了如下图所示的几个基本类,其中最常用和重要的类是Event、EventBase和EventConfig,那么我们就从这三个开始吧。考虑到大多数正在阅读本文的你我和其他不知名的物种可能都不是C语言的老手,我不得不使用一些可能不合适的案例和比喻来尝试介绍这些概念。libevent中有五个字母是event,其实就是“eventisking”的意思。Event类是一个生成器,生成各种类型的事件,比如定时器事件,读写事件等。为了增强国家荣誉感,我们把这些各种各样的事件比作各种战斗机:比如J-10,J-15和J-15J-20。EventBase类比较容易介入。这东西分明就是航空母舰。为了增强国家荣誉感,我们把EventBase类当作辽宁舰。各种Event都要靠EventBase维持生计。这与战斗机有信心和辽宁舰一起飞得更高更远的道理是一样的。首先要有航母(EventBase),然后航母(EventBase)上挂着一架战斗机(Event)。EventConfig是一个配置类。实例化后的对象可以作为参数传递给EventBase类,这样在初始化EventBase类时,会根据这个配置初始化不同的EventBase实例。打个比方,这个级有点类似于辽宁舰的舰岛,可以配置指挥整个辽宁舰。航母的发展趋势不需要舰岛。同样,在实例化EventBase类时,也不需要传入EventConfig对象,直接实例化也没有问题。我们先写一个php定时器来步入代码的节奏。定时器是大家常用的工具。一般phper说起定时器,第一个想到的就是linux中的crontab。没有crontab,phper真的不能混吗?是的,真的很丢人,现实告诉我们就是这样,没有crontab他们真的混不下去。那么,是时候通过纯php来实现一波定时器了!注意是真的纯php,连Event扩展都不用的那种。add($tick);//eventBase进入循环state(辽宁舰!加油!)$eventBase->loop();将代码保存为tick.php,然后在phptick.php中执行,如下图:这个定时器是一个持久化定时器(每隔X次就会执行一次),如果你想要一个一次性的定时器(每X次执行一次,执行完后不执行),则将上述代码中的“Event::TIMEOUT|Event::PERSIST”修改为“Event::TIMEOUT”即可。如果你有一些自定义的用户数据传递给回调函数,你可以使用newEvent()的第五个参数,这五个参数可以用于回调函数,如下:'woshishui',));需要强调的是newEvent()这行代码,我贴出原型给大家看看:publicEvent::__construct(EventBase$base,mixed$fd,int$what,callable$cb[,mixed$arg=NULL])第一个参数是一个eventBase对象,第二个参数是一个文件描述符,可以是监听套接字,连接套接字,fopen打开的文件或流等。如果是时钟时间,则传入-1。对于其他信号事件,使用相应的信号常量,如SIGHUP、SIGTERM等。第三个参数表示事件类型,后面依次为Event::READ、Event::WRITE、Event::SIGNAL、Event::TIMEOUT。其中,添加Event::PERSIST表示持久化发生,而不是只发生一次就不再响应。例如,事件::阅读|Event::PERSIST表示某个文件描述在第一次可读时发生一次,以后如果再次可读并准备好会继续再次发生。第四个参数很熟悉,就是事件回调,意思是当一个事件发生的时候,具体应该做什么?对应的第五个参数为自定义数据,会传递给第四个参数的回调函数,此数据可用于回调函数。通过上面的案例代码,我们可以总结一下每天的流程:创建EventConfig(非必填)创建EventBase创建Event挂起Event,即执行Event对象的add方法。如果不执行add方法,则事件对象无法挂起,也不会执行EventBase的执行进入循环,也就是loop方法清空定时器代码,我们尝试解决一个信号问题。比如我们的进程是一个驻留在内存中的守护进程,它在接收到某个信号后会做出相应的动作,比如进程在接收到term信号后退出,在接收到usr1信号后执行reload等。add();//进入循环echo"Enter循环”。PHP_EOL;$eventBase->loop();将代码保存为tick.php,然后执行phptick.php,代码进入了一个循环,这时我们再打开一个终端,输入psaux|greptick查看一个php进程的pid进程号,发送一个term信号给这个过程,如下图所示:奇怪,从第一张图来看,确实是收到了signal这个词,但是奇怪为什么php进程退出了?因为没有添加Event::PERSIST,修改如下代码:.PHP_EOL;});IO多路复用的方法一共有三种:select、poll和epoll(Mac下称为kqueue),那么我们现在的事件扩展用的是哪种方法呢?那么,我们再来一波:getMethod().PHP_EOL;//跑了半天的config要真动手了这次$eventConfig=newEventConfig;//避免使用方法kqueue$eventConfig->avoidMethod('kqueue');//使用config初始化事件base$eventBase=newEventBase($eventConfig);echo"当前事件的方法是:".$eventBase->getMethod().PHP_EOL;保存代码,然后执行,可以看到如下图的结果:那么,还有一些小偷继续问,如何确认上面提到的边沿触发和水平触发?既然使用了epoll或者kqueue,就必须使用边缘触发getFeatures();//看不到For这个判断条件,请反省自己缺少“位操作”Event".PHP_EOL;}if($features&EventConfig::FEATURE_FDS){echo"Anyfiledescriptor,notjustsocket".PHP_EOL;}运行结果如下图所示:小小假装被迫总结,今天这些内容就是描述事件的三个??基本类别,下一章仍然是将这三个家伙与IO操作结合起来。[原文地址:https://blog.ti-node.com/blog...][原文地址:https://blog.ti-node.com/blog...]