协程

defer

  • 协程客户端的对象结构体,设置client->defer = 1表示启用了defer延迟收包
  • 设置client->defer_yield = 1表示进入了wait状态

事件监听

因为swoole底层的EventLoop总是在运行的,因此可能某个协程客户端没有yield也会收到包。底层需要对数据进行缓存。

Client

自动保存到ccp->result内存中。为了避免收到的数据过多,导致内存占用过大,超过cli->buffer_input_size的长度后,调用swClient_sleep移除事件监听,不再收包。当PHP代码中调用了$client->recv取出ccp->result中的数据后,调用swClient_wakeup重新监听可读事件,继续收包。

Http\Client & MySQL & Redis & Http2Client

因为这些客户端是请求应答式的,因此底层会直接存储zval结果变量,PHP代码中调用recv时返回结果。

WebSocket\Client

WebSocket与其他客户端不同,onMessage时会将zval消息变量,保存到swLinkedList队列中。队列长度超过16后,自动移除事件监听。recv之后恢复接收。

超时机制

协程客户端的recv方法均提供了timeout参数,设置timeout后底层会添加一个定时器,如果定时器先于onReceive执行,证明recv超时,底层会立即返回false,并设置错误码,一般为ETIMEOUT

如果onReceive先执行,会清除定时器。