多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# swoole\_event\_add [TOC] 将一个socket加入到底层的`reactor`事件监听中。此函数可以用在`Server`或`Client`模式下。 ## 函数原型 ~~~ bool swoole_event_add(mixed $sock, mixed $read_callback, mixed $write_callback = null, int $flags = null); ~~~ ## 参数 参数1`$sock`可以为以下四种类型: * `int`,就是文件描述符,包括`swoole_client->$sock`、`swoole_process->$pipe`或者其他`fd` * `stream`资源,就是`stream_socket_client/fsockopen`创建的资源 * `sockets`资源,就是`sockets`扩展中`socket_create`创建的资源,需要在编译时加入`./configure --enable-sockets` * `object`,`swoole_process`或`swoole_client`,底层自动转换为管道或客户端连接的`socket` 参数2`$read_callback`为可读事件回调函数,参数3`$write_callback`为可写事件回调函数,此参数可以是字符串函数名、对象+方法、类静态方法或匿名函数,当此`socket`可读或者可写时回调指定的函数。 参数4`$flags`为事件类型的掩码,可选择关闭/开启可读可写事件,如`SWOOLE_EVENT_READ`,`SWOOLE_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_add`将`socket`加入到事件监听后,底层会自动将该`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不会阻塞进程,这行代码会顺序执行 ~~~ ## 回调函数 * 在可读事件回调函数中必须使用`fread`、`recv`等函数读取`socket`缓存区中的数据,否则事件会持续触发,如果不希望继续读取必须使用`Swoole\Event::del`移除事件监听 * 在可写事件回调函数中,写入`socket`之后必须调用`Swoole\Event::del`移除事件监听,否则可写事件会持续触发 * 执行`fread`、`socekt_recv`、`socket_read`、`Swoole\Client::recv`返回`false`,并且错误码为`EAGAIN`时表示当前`socket`接收缓存区内没有任何数据,这时需要加入可读监听等待`EventLoop`通知 * 执行`fwrite`、`socket_write`、`socket_send`、`Swoole\Client::send`操作返回`false`,并且错误码为`EAGAIN`时表示当前`socket`发送缓存区已满,暂时不能发送数据。需要监听可写事件等待`EventLoop`通知