Event::add

将一个socket加入到底层的reactor事件监听中。此函数可以用在ServerClient模式下。

函数原型

bool Swoole\Event::add(mixed $sock, mixed $read_callback, mixed $write_callback = null, 
        int $flags = null);

参数

参数1$sock 可以为以下四种类型:

  • int,就是文件描述符,包括swoole_client->$sockswoole_process->$pipe或者其他fd
  • stream资源,就是stream_socket_client/fsockopen创建的资源
  • sockets资源,就是sockets扩展中socket_create创建的资源,需要在编译时加入 ./configure --enable-sockets
  • objectswoole_processswoole_client,底层自动转换为管道或客户端连接的socket

参数2$read_callback为可读事件回调函数,参数3$write_callback为可写事件回调函数,此参数可以是字符串函数名、对象+方法、类静态方法或匿名函数,当此socket可读或者可写时回调指定的函数。

参数4$flags为事件类型的掩码,可选择关闭/开启可读可写事件,如SWOOLE_EVENT_READSWOOLE_EVENT_WRITE,或者SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE

在 Server 程序中使用时,必须在 Worker 进程启动后使用。在 Server::start 之前不得调用任何异步 IO 接口

返回值

  • 添加事件监听成功成功返回true
  • 添加失败返回false,请使用swoole_last_error获取错误码
  • 已添加过的socket不能重复添加,可以使用swoole_event_set修改socket对应的回调函数和事件类型

使用Swoole\Event::addsocket加入到事件监听后,底层会自动将该socket设置为非阻塞模式

使用实例

$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30);
fwrite($fp,"GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n");

Swoole\Event::add($fp, function($fp) {
    $resp = fread($fp, 8192);
    //socket处理完成后,从epoll事件中移除socket
    swoole_event_del($fp);
    fclose($fp);
});
echo "Finish\n";  //Swoole\Event::add 不会阻塞进程,这行代码会顺序执行

回调函数

  • 在可读事件回调函数中必须使用freadrecv等函数读取socket缓存区中的数据,否则事件会持续触发,如果不希望继续读取必须使用Swoole\Event::del移除事件监听
  • 在可写事件回调函数中,写入socket之后必须调用Swoole\Event::del移除事件监听,否则可写事件会持续触发
  • 执行freadsocekt_recvsocket_readSwoole\Client::recv返回false,并且错误码为EAGAIN时表示当前socket接收缓存区内没有任何数据,这时需要加入可读监听等待EventLoop通知
  • 执行fwritesocket_writesocket_sendSwoole\Client::send操作返回false,并且错误码为EAGAIN时表示当前socket发送缓存区已满,暂时不能发送数据。需要监听可写事件等待EventLoop通知


  • json

    swoole_event不可以用在php-fpm中吧,我测过通过Url请求php,返回swoole_event_add(): async-io must use in cli environment,异常

  • D
    D

    提示很清楚啊,必须在cli模式下运行。

  • 秣马儿

    swoole_event_add 提示 PHP Warning: swoole_event_add(): fd argument must be valid PHP stream resource in /home/gaoshijie/swoole_load3.php on line 28 PHP Warning: swoole_event_add(): unknow type. in /home/gaoshijie/swoole_load3.php on line 28 请问是怎么回事? 第一个参数我传的就是socket_create函数返回值啊。

  • thinkpc

    process下貌似不工作

  • Tadashi

    在daemon模式下,swoole_event_add对stream_socket_client/fsockopen只能在进程结束后才会调用回调函数?

  • 刘锋

    使用这个函数能添加 连接出错和关闭的事件监听吗?

  • 天弋

    swoole_event_add貌似只在server->start()之前添加有效,server->start()之后使用这个函数没有作用,是这样吗,swoole版本1.9.4求解答。

  • 飞鸿影

    fwrite($fp, "GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n");
    

  • fy

    添加到reactor线程监听后,如果监听到描述符准备就绪后是怎么执行回调函数呢,会新起一个进程执行么?

  • 当时只道是寻常

    PHP Warning: swoole_event_add(): fd argument must be valid PHP stream resource in /mnt/hgfs/share/phpserver/examples/event/sockets.php on line 52

  • kog

    缺少error的callback; 当fd出错时,会导致服务死循环 例子: 子进程中监听STDIN, 父进程被kill后,子进程CPU 100%