在4.4
之前的版本中,Swoole
一直不支持CURL
协程化,在代码中无法使用curl
。由于curl
使用了libcurl
库实现,无法直接hook
它的socket
,4.4
版本使用SwooleCoroutineHttpClient
模拟实现了curl
的API
,并在底层替换了curl_init
等函数的C Handler
。
提示
CURL Hook
的特性尚处于试验阶段,请勿在生产环境中直接使用- 暂不支持文件上传、
CURL Multi
- 仍然需要依赖
curl
,请务必安装curl
扩展
支持的特性列表
- GET/POST
- Header
- Cookie
- Https
经过验证
Guzzle CURL
完全可以使用
开启
使用Runtime::enableCoroutine
来开启CURL Hook
。
代码语言:javascript复制默认不开启
CURL Hook
SwooleRuntime::enableCoroutine(SWOOLE_HOOK_ALL);
SwooleRuntime::enableCoroutine(SWOOLE_HOOK_CURL);
使用
代码语言:javascript复制$n = 10;
while($n--) {
go(function () {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.xinhuanet.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
if ($output === FALSE) {
echo "CURL Error:" . curl_error($ch);
}
curl_close($ch);
echo strlen($output) . " bytesn";
});
}
要将上面两段代码合并到一个文件中执行
运行结果
代码语言:javascript复制htf@LAPTOP-0K15EFQI:~/swoole-src/examples$ time php curl.php
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
177173 bytes
real 0m0.534s
user 0m0.031s
sys 0m0.297s
可以看到整个程序是并行的,进程没有任何阻塞。
strace 跟踪
使用strace
跟踪发现,所有系统调用均变成epoll
socket
的异步非阻塞调用了。
munmap(0x7fc021950000, 2101248) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 19, NULL) = 0
recvfrom(19, "3442@o36234010240#337=J2=274337201307=3O32434235s7\167^"23"..., 65536, 0, NULL, NULL) = 19559
close(19) = 0
write(1, "177115 bytesn", 13) = 13
munmap(0x7fc021110000, 2101248) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 18, NULL) = 0
recvfrom(18, "3442@o36234010240#337=J2=274337201307=3O32434235s7\167^"23"..., 65536, 0, NULL, NULL) = 19559
close(18) = 0
write(1, "177115 bytesn", 13) = 13
munmap(0x7fc021320000, 2101248) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=238, tv_nsec=802835000}) = 0
time(NULL) = 1559698606 (2019-06-05T09:36:46 0800)
futex(0x7fffd9e01ce0, FUTEX_WAKE_PRIVATE, 2147483647) = 4
futex(0x7fffd9e01c90, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7fc023ff09d0, FUTEX_WAIT, 56, NULL) = -1 EAGAIN (Resource temporarily unavailable)
epoll_ctl(3, EPOLL_CTL_DEL, 5, NULL) = 0
close(5) = 0
close(6) = 0
close(2) = 0
close(1) = 0
close(0) = 0
munmap(0x7fc028fa0000, 2231560) = 0
munmap(0x7fc028d1f000, 2624568) = 0
close(3) =
划重点
- 在4.4的版本,支持用PHP代码写Swoole的扩展来替换掉PHP的类或方法,这样将针大大提升程序的兼容性,像CURL, MongoDb这些也可以做到无缝支持协程了
- ----------伟大的分割线-----------