该版本会为 onConnect、onReceive、onPacket 等回调函数,默认开启协程并发回调。
参见源码:
https://github.com/swoole/swoole-src/blob/v4.0.0/swoole_server.c#L884
https://github.com/swoole/swoole-src/blob/v4.0.0/swoole_server.c#L990
测试 TCP onReceive 代码
public function onReceive($server, $fd, $fromId, $data) {
$cid = \Swoole\Coroutine::getuid();
$this->log("Coro: {$cid} Receive Buffer: $data");
}
测试方式 nc 发 TCP 包
# proto.log 文件为一个大数据包
nc 127.0.0.1 10091 < proto.log
[eaglewu@xxx ~]$ php bug.php
Server started
[1557302993.2989] 1 connected
[1557302993.2991] Coro: 3 Receive Buffer: )?�{"sid":"EP7DheyMa9SSK","pid":....省略.....,"9997331","64
[1557302994.2993] Coro: 4 Receive Buffer: 72269824","1
[1557302995.2995] Coro: 5 Receive Buffer: 218964480","1241181184",....省略....:1556278091}
[1557302996.2996] 1 closed
可以看到 一个包,分三次回调 onReceive
并都在不同的携程内,协程 ID 分别为 3,4,5
比较有疑惑的点在于:
- 这三个协程在某些极端情况下,能否保证先后顺序?
- 是否会等待前一个协程回调任务执行完成后(包含回调函数本身执行时间),再执行下一个协程内的回调任务?
配置选项:enable_coroutine
从 v4.0.1 添加的,所以对 v4.0.0 无任何效果,结果同上。
https://github.com/swoole/swoole-src/blob/v4.0.1/swoole_server.c#L857,L866
默认 enable_coroutine
为启用状态,默认行为与上面结果类似,都是不同的协程进行回调。
设置 enable_coroutine = false
后结果如下:
[root@xxx ~]# php bug.php
Server started
[1557304681.8939] 1 connected
[1557304681.8941] Coro: -1 Receive Buffer: )?�{"sid":"EP7DheyMa9":......省略.....328960","9997331"64
[1557304682.8944] Coro: -1 Receive Buffer: 72269824","12189680"......省略.....12,"gseq_32":1556278091}
[1557304683.8945] 1 closed
本次分了两个包进行 onReceive
回调,在尝试获取协程 ID时,均失败,得到 -1
v4.0.0
版本确实每个回调在不同的协程内enable_coroutine
对v4.0.0
无效v4.0.1
关闭enable_coroutine
对业务使用透明(暂未考虑性能问题)