头图

Swoole v4.6.5 is released, adding native curl multi support

沈唁
中文

v4.6.5 The version has no downward incompatibility changes. It mainly enhances the native curl hook and supports curl multi

  • Support native curl multi

The premise of using native curl hook is to enable the --enable-swoole-curl option when compiling the Swoole extension

You can use the following code to test:

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);
});

After supporting curl multi, it also supports Guzzle indirectly, not need to change any code to support it.

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;
});

Also added some unit tests for Guzzle.

  • Allows the use of arrays to set headers in Responses that use HTTP/2

From v4.6.0 of version Swoole \ Http \ Response duplication of the same support $key the HTTP head, and $value support multiple types, such as array , object , int , float , the bottom will be toString conversion, will be removed and trailing spaces and line breaks.

But it does not support HTTP/2, see issue #4133

Support is also provided in this version:

$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();

You can use the above code to test, and use the curl command to test the results

$ 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

Update log

The following is the complete update log:

New API

  • Add count method to WaitGroup (swoole/library#100) (@sy-records) (@deminy)

Enhance

  • Support native curl multi (#4093) (#4099) (#4101) (#4105) (#4113) (#4121) (#4147) (swoole/[email protected]) (@matyhtf) (@sy-records ) (@huanghantao)
  • Allows the use of arrays to set headers in Responses that use HTTP/2

repair

  • Fix NetBSD build (#4080) (@devnexen)
  • Fix OpenBSD build (#4108) (@devnexen)
  • Fix illumos/solaris build, only member aliases (#4109) (@devnexen)
  • Fix that the heartbeat detection of SSL connection does not take effect when the handshake is not completed (#4114) (@matyhtf)
  • host in host:port when Http\Client uses a proxy (#4124) (@Yurunsoft)
  • Fix the settings of header and cookie in Swoole\Coroutine\Http::request (swoole/library#103) (@leocavalcante) (@deminy)

Kernel

  • Support asm context on BSD (#4082) (@devnexen)
  • Use arc4random\_buf to implement getrandom under FreeBSD (#4096) (@devnexen)
  • Optimize darwin arm64 context: delete workaround and use label (#4127) (@devnexen)

test

  • Add alpine build script (#4104) (@limingxinleo)

阅读 3.1k

Swoole
PHP的协程框架
avatar
沈唁
禅道 研发专家
1.7k 声望
1.2k 粉丝
0 条评论
avatar
沈唁
禅道 研发专家
1.7k 声望
1.2k 粉丝
文章目录
宣传栏