swoole_event_add
最后更新于:2022-04-02 06:37:53
# 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`通知
';