协程
优质
小牛编辑
132浏览
2023-12-01
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
先执行,会清除定时器。