Swoole v4.6.5 版本发布,增加原生curl multi支持

简介: v4.6.5 版本没有向下不兼容改动,主要对原生 curl hook 进行了一些增强,支持了 curl mult
  • 支持原生 curl multi

使用原生 curl hook 的前提是在编译 Swoole 扩展时开启--enable-swoole-curl选项

可以使用以下代码进行测试:

use Swoole\Runtime;
use function Swoole\Coroutine\run;
Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);
run(function () {
    $ch1 = curl_init();
    $ch2 = curl_init();
    // 设置URL和相应的选项
    curl_setopt($ch1, CURLOPT_URL, "http://www.baidu.com/");
    curl_setopt($ch1, CURLOPT_HEADER, 0);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch2, CURLOPT_URL, "http://www.gov.cn/");
    curl_setopt($ch2, CURLOPT_HEADER, 0);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
    $mh = curl_multi_init();
    curl_multi_add_handle($mh, $ch1);
    curl_multi_add_handle($mh, $ch2);
    $active = null;
    // 执行批处理句柄
    do {
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) {
        $n = curl_multi_select($mh);
        if ($n != -1) {
            do {
                $mrc = curl_multi_exec($mh, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
    }
    $info1 = curl_multi_info_read($mh);
    $info2 = curl_multi_info_read($mh);
    $info3 = curl_multi_info_read($mh);
    assert($info1['msg'] === CURLMSG_DONE);
    assert($info2['msg'] === CURLMSG_DONE);
    assert($info3 === false);
    assert(strpos(curl_multi_getcontent($ch1),'baidu.com') !== false);
    assert(strpos(curl_multi_getcontent($ch2),'中央人民政府门户网站') !== false);
    curl_multi_remove_handle($mh, $ch1);
    curl_multi_remove_handle($mh, $ch2);
    curl_multi_close($mh);
});

支持 curl multi 之后,也就间接的支持了 Guzzle,无需更改任何代码,即可支持。

include __DIR__ . '/vendor/autoload.php';
use Swoole\Coroutine\Barrier;
use Swoole\Runtime;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);
const N = 4;
run(function () {
    $barrier = Barrier::make();
    $result = [];
    go(function () use ($barrier, &$result) {
        $client = new Client();
        $promises = [
            'baidu' => $client->getAsync('http://www.baidu.com/'),
            'qq' => $client->getAsync('https://www.qq.com/'),
            'gov' => $client->getAsync('http://www.gov.cn/')
        ];
        $responses = Promise\Utils::unwrap($promises);
        assert(strpos($responses['baidu']->getBody(),'百度') !== false);
        assert(strpos(iconv('gbk', 'utf-8', $responses['qq']->getBody()),'腾讯') !== false);
        assert(strpos($responses['gov']->getBody(),'中华人民共和国') !== false);
        $result['task_1'] = 'OK';
    });
    go(function () use ($barrier, &$result) {
        $client = new Client(['base_uri' => 'http://httpbin.org/']);
        $n = N;
        $data = $promises = [];
        while ($n--) {
            $key = 'req_' . $n;
            $data[$key] = uniqid('swoole_test');
            $promises[$key] = $client->getAsync('/base64/' . base64_encode($data[$key]));
        }
        $responses = Promise\Utils::unwrap($promises);
        $n = N;
        while ($n--) {
            $key = 'req_' . $n;
            assert($responses[$key]->getBody() === $data[$key]);
        }
        $result['task_2'] = 'OK';
    });
    Barrier::wait($barrier);
    assert($result['task_1'] === 'OK');
    assert($result['task_2'] === 'OK');
    echo 'Done' . PHP_EOL;
});

同时也还添加了一些 Guzzle 的单元测试。

  • 允许在使用 HTTP/2 的 Response 中使用数组设置 headers

v4.6.0 版本开始 Swoole\Http\Response 支持重复设置相同 $keyHTTP 头,并且 $value 支持多种类型,如 arrayobjectintfloat,底层会进行 toString 转换,并且会移除末尾的空格以及换行。

但是未支持 HTTP/2 的,详情见 issue #4133

在此版本中也进行了支持:

$http = new Swoole\Http\Server('127.0.0.1', 9501);
$http->set(['open_http2_protocol' => true]);
$http->on('request', function ($request, $response) {
    $response->header('Test-Value', [
        "a\r\n",
        'd5678',
        "e  \n ",
        null,
        5678,
        3.1415926,
    ]);
    $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();

可以使用以上代码进行测试,并使用 curl 命令进行测试结果

$ curl --http2-prior-knowledge -v http://localhost:9501
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 9501 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9501 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fe9e9009200)
> GET / HTTP/2
> Host: localhost:9501
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< test-value: a
< test-value: d5678
< test-value: e
< test-value: 5678
< test-value: 3.1415926
< server: swoole-http-server
< date: Fri, 09 Apr 2021 11:04:39 GMT
< content-type: text/html
< content-length: 28
<
* Connection #0 to host localhost left intact
<h1>Hello Swoole. #6944</h1>* Closing connection 0

更新日志


下面是完整的更新日志:

新增 API

  • 在 WaitGroup 中增加 count 方法(swoole/library#100) (@sy-records) (@deminy)

增强

  • 支持原生 curl multi (#4093) (#4099) (#4101) (#4105) (#4113) (#4121) (#4147) (swoole/swoole-src@cd7f51c) (@matyhtf) (@sy-records) (@huanghantao)
  • 允许在使用 HTTP/2 的 Response 中使用数组设置 headers

修复

  • 修复 NetBSD 构建 (#4080) (@devnexen)
  • 修复 OpenBSD 构建 (#4108) (@devnexen)
  • 修复 illumos/solaris 构建,只有成员别名 (#4109) (@devnexen)
  • 修复握手未完成时,SSL 连接的心跳检测不生效 (#4114) (@matyhtf)
  • 修复 Http\Client 使用代理时host中存在host:port产生的错误 (#4124) (@Yurunsoft)
  • 修复 Swoole\Coroutine\Http::request 中 header 和 cookie 的设置 (swoole/library#103) (@leocavalcante) (@deminy)

内核

  • 支持 BSD 上的 asm context (#4082) (@devnexen)
  • 在 FreeBSD 下使用 arc4random\_buf 来实现 getrandom (#4096) (@devnexen)
  • 优化 darwin arm64 context:删除 workaround 使用 label (#4127) (@devnexen)

测试

  • 添加 alpine 的构建脚本 (#4104) (@limingxinleo)
目录
相关文章
|
安全 API 网络安全
Swoole v4.6.0 版本发布,支持原生 curl 协程客户端
Swoole v4.6.0 版本发布了,同样也是 2021 年的首个版本更新。 作为一个 y 版本发布,此次更新也包含了不兼容的修改以及许多的新功能
705 0
|
Web App开发
Selenium自动化chrome驱动版本匹配但是调用浏览器失败:Only local connections are allowed. 问题解决
Selenium自动化chrome驱动版本匹配但是调用浏览器失败:Only local connections are allowed. 问题解决
373 0
|
网络协议 安全 网络安全
Swoole v4.6 版本新特性之 SNI 支持
Swoole 在 v4.6.0 版本中对 SNI 进行了支持,这篇文章就对这个新特性进行一些演示和说明。
211 0
Swoole v4.6 版本新特性之 SNI 支持
|
移动开发 网络协议 数据格式
Swoole v4.6 版本新特性之 Http\Request 增强
在 4.6 版本中,对 Swoole\Http\Request 进行了一些增强
188 0
|
JSON API 数据格式
Swoole v4.5.7 版本发布,新增--enable-swoole- json编译选项
在上个版本中添加的 swoole_substr_json_decode 函数,由于少部分用户的扩展依赖顺序问题,所以添加了一个编译选项--enable-swoole-json,用于启用 swoole_substr_json_decode 支持
169 0
|
API
Swoole v4.6 版本新特性之 Http\Response 增强
在 4.6 版本中,对 Swoole\Http\Response 进行了一些增强
187 0
|
安全 NoSQL API
Swoole v4.8.0 版本发布,增加 Swoole Dashboard 面板
此版本包含了新功能、BUG 修复以及向下不兼容的改动。
383 0
|
域名解析 网络协议 NoSQL
Swoole v4.7 版本预览之支持 c-ares
c-ares 是一个异步 DNS 解析库。 它适用于需要在不阻塞的情况下执行 DNS 查询或需要并行执行多个 DNS 查询的应用程序。
530 0
|
网络协议 关系型数据库 MySQL
Swoole v4.7.0 版本正式发布,Swoole 官网支持直接运行 Swoole 代码
在 Swoole 官网增加了 在线运行 的按钮,可以直接运行首页提供的一些示例代码,当然也可以手动输出一些 PHP 代码进行测试。 可以访问 Swoole 官网首页进行测试使用:https://www.swoole.com/ 目前还处于测试阶段,有遇到 BUG 可以向识沃科技客服反馈或交流群中反馈。
243 0