该版本会为 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对业务使用透明(暂未考虑性能问题)