libevent

大路 Linux 2023-10-11 158

libevent是针对php封装的一个事件库,封装了不同平台的进行事件编程的一个库。可以进行多线程编程等。

libevent(这里的libevent是一个库)封装了linux底层的epoll, 安装Libevent(这里的libevent是一个PHP扩展, 用来连接PHP与库)扩展或者Event扩展让php可以调用libevent封装好的函数. 支持I/O, 定时器, 信号.

我们常听的Reactor模型, libevent已经封装好了. 直接调用EventBaseEvent类就是使用Reactor模型. 但是有些高性能的服务器, 如nginxswoole没有依赖libevent库, 而是自己封装了底层的epoll, 实现Reactor模型.

基础来说有Event和EventBase两个方法,Event自Event_Base拓展而来

stream_socket_server

1、stream_socket_server 是PHP自带的接口,无需安装任何扩展。

2、stream_socket_server 接口使用非常简单,比如创建一个socket监听服务,socket_* 需要好多行代码才能搞定,但是stream_socket_server只需一行就搞定了。

3、stream_socket_server 创建的socket属于stream类型,可以用stream相关的函数操作,fread、fwrite等等。也可以使用stream相关的高级特性,过滤器、streamWrapper、SSL加密等。

4、stream_socket_* 系列函数的缺点是很多socket选项无法精确设置。所以当 stream_socket 无法完成精确设置的时候,可以借助socket_import_stream将stream_socket转换成底层sockets,然后就可以通过socket_set_option设置stream_socket的socket选项

示例

I/O示例

<?php



$fd = stream_socket_server("tcp://0.0.0.0:9001", $errno, $errstr);



stream_set_blocking($fd, 0);



$event_base = new EventBase();



$event = new Event($event_base, $fd, Event::READ | Event::PERSIST, function ($fd) use (&$event_base) {

 $conn = stream_socket_accept($fd);



 fwrite($conn, "HTTP/1.0 200 OK\r\nContent-Length: 2\r\n\r\nHi");

 fclose($conn);

}, $fd);



$event->add();



$event_base->loop();


定时器示例





function setTimeout($second, $callback)

{

    $event_base = new EventBase();



    $event = Event::timer($event_base, $callback);



    $event->add($second);



    $event_base->loop();

}



function setInterval($second, $callback)

{

    $func = function() use ($second, $callback, &$func) {

        call_user_func($callback);

        setTimeout($second, $func);

    };



    setTimeout($second, $func);

}





setInterval(1, function() {

    echo "hello", PHP_EOL;

});


信号示例


<?php 



$pid = pcntl_fork();



if ($pid > 0) {

    sleep(1);

    posix_kill($pid, SIGINT);

    exit(0);



} elseif ($pid == 0) {

    $event_base = new EventBase();



    $event = Event::signal($event_base, SIGINT, function() use (&$event, &$event_base) {

        echo "sigint", PHP_EOL;

        $event->del();

        $event_base->free();

        exit(0);

    });



    $event->add();



    $event_base->loop();



} else {

    printf("fork failed");

}


标签: