关于php stream_select方法的研究理解
function stream_select (array &$read, array &$write, array &$except, $tv_sec, $tv_usec = null) {}
stream_select函数返回的条件为:
- $read数组中的任何一个连接发生可读事件
- $write数组中任何一个连接发生可写事件
- $except数组中的任何一个连接有带外数据到来(OOB)
- 当前进程收到系统信号(signal), 如:pcntl_alarm产生的闹钟信号,也就是说信号可以中断stream_select的调用,使其立即返回
- stream_select阻塞等待时间超过($tv_sec+$tv_usec)的时间总值,如果$tv_sec=&null时,则无限阻塞直到上面4种返回条件中的任何一种发生了
返回值
- 返回值为监听的所有连接中发生状态改变的连接数,比如当有3个连接发生可写事件,导致方法返回,则返回值为3(integer类型)
- 如果是被系统信号中断返回值为false并输出警告(被信号中断).
- 如果等待直到超时都没任何事件发生,则返回0
关于带外数据
- 带外数据长度只支持1个字符,用于发生紧急的数据,比如暂停这类的功能,就是发生一个紧急字符优先发送到对端,进而紧急处理
stream_select是如何判断连接可读可写的
- 每一个socket连接都有一个读缓冲区(readBuffer)和一个写缓冲区(writeBuffer). 每个缓冲区都有一个低水位标记. 接收缓存区低水位标记(用于判断可读)和发送缓存区低水位标记(用于判断可写)stream_select底层通过遍历所有待监听的socket连接,并通过下面的方式判断每个连接的可读可写:
- 可读: 当readBuffer中的数据量”大等于”接收低水位标记值时. 默认接收低水位标记值=1; 还有另一种情况发生可读事件, 就是对端关闭连接时, 这时可以使用 !is_resource($fd) || feof($fd)==true 判断连接已经断开
- 可写: 当writeBuffer中剩余的可用空间”大等于”发送低水位标记值时, 默认发送低水位标记值=2048