swoole_event_add
将一个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
通知