zoukankan      html  css  js  c++  java
  • php libev扩展使用

           在WorkerMan源码分析 - 实现最简单的原型文章中提到了libevent网络库,前者和libev都是事件驱动编程库高性能。简单说libev对libevent做了改进和精简。libevent使用全局变量,导致非线程安全。它的watcher结构也过大,把I/O、计时器、信号句柄整合在一起。而且(作者认为)libevent的附加组件如http和dns库都实现不好,且有安全问题。libev对这些地方做了改进,避免使用全局变量,拆分watcher等。另外libev去掉了外部库(比如http和dns),只专注于事件驱动服务,所以更精简。

    安装libev扩展

    地址:https://pecl.php.net/package/ev

    实例

    定时器实现

    <?php
    //定时器的实现,2秒后每2秒触发1次注册的事件
    
    $loop = new EvLoop();
    
    function timers()
    {
        echo date("Y-m-d H:i:s") . "
    ";
    }
    
    //$event = $loop->timer(2,0,'timers');
    $event = $loop->timer(2,2,'timers');
    $loop->run();

    结果如下:

    2018-04-25 16:57:54
    2018-04-25 16:57:55
    2018-04-25 16:57:56
    2018-04-25 16:57:57

    基于事件循环 异步io 的socket读写

     1 <?php
     2 $loop = new EvLoop();
     3 $arr = [];
     4 $data = "hello world
    ";
     5 
     6 function add($fd,$ev,$func){
     7     global $arr,$loop;
     8     $func = getStreamListenerClosure($fd,$func);
     9     //创建观察者监听io $ev事件
    10     $event = $loop->io($fd,$ev,$func);
    11     $arr[posix_getpid()][(int)$fd] = $event;
    12 }
    13 
    14 //返回闭包
    15 function getStreamListenerClosure($stream, $listener){
    16     return function () use ($stream,$listener){
    17         call_user_func($listener,$stream);
    18     };
    19 }
    20 
    21 //
    22 function baseRead($socket){
    23     $buffer = @fread($socket, 2);
    24 
    25     if ($buffer == "
    "){
    26         //结尾
    27         fclose($socket) && removeStream($socket);
    28     } else {
    29         echo $buffer;
    30     }
    31 }
    32 
    33 //
    34 function baseWrite($socket){
    35 
    36     global $data;
    37 
    38     $written = fwrite($socket, $data,1);
    39     if ($written === strlen($data)) {
    40         fclose($socket);
    41         removeStream($socket);
    42     } else {
    43         $data = substr($data, $written);
    44     }
    45 
    46 }
    47 
    48 //停止指定事件并销魂指定流资源
    49 function removeStream($stream){
    50 
    51     global $arr,$loop;
    52     $key = (int)$stream;
    53     $pid = posix_getpid();
    54 
    55     if (!isset($arr[$pid][$key]))
    56         return;
    57 
    58     $arr[$pid][$key]->stop();
    59     unset($arr[$pid][$key]);
    60 }
    61 
    62 function acceptConnection($socket){
    63 
    64     $new_socket = @stream_socket_accept($socket);
    65     if (!$new_socket) {
    66         return;
    67     }
    68 
    69     stream_set_blocking($new_socket,false);
    70     stream_set_read_buffer($new_socket, 0);
    71 
    72     //add($new_socket,Ev::READ,'baseRead');
    73     add($new_socket,Ev::WRITE,'baseWrite');
    74 
    75 }
    76 
    77 //定时器
    78 function timers()
    79 {
    80     echo date("Y-m-d H:i:s") . "
    ";
    81 }
    82 
    83 $socketmain = stream_socket_server('tcp://127.0.0.1:7777');
    84 //非阻塞
    85 stream_set_blocking($socketmain,false);
    86 
    87 add($socketmain,Ev::READ,'acceptConnection');
    88 
    89 $event = $loop->timer(2,2,'timers');
    90 
    91 $loop->run();
    92 
    93 /*
    94 while (true){
    95     //EV::RUN_ONCE 事件只触发1次
    96     $loop->run(EV::RUN_ONCE);
    97 }
    98 */

    利用telnet测试,具体参考WorkerMan源码分析 - 实现最简单的原型文章。

  • 相关阅读:
    mysql 字符串先按照长度排序再按照ASCII码排序
    JMeter 压力测试文档
    Linux C监听鼠标键盘操作
    ubuntu 笔记本触摸板失灵
    git commit之后,想撤销commit
    清空iptables防火墙
    在k8s中搭建sonarqube并集成到jenkins
    redis集群搭建
    四叶草防火墙内外网映射
    k8smaster节点更换ip
  • 原文地址:https://www.cnblogs.com/loveyouyou616/p/8945863.html
Copyright © 2011-2022 走看看