如何使用 GuzzleHttp 执行并发请求

Tal*_*boy 2 php guzzle guzzle6

如何使用 Guzzle 6 创建 5 个具有以下条件的异步请求:

  • 所有请求同时开始
  • 我希望所有请求的超时值为 500 毫秒。如果请求超时,我不希望它中断其他请求
  • 如果请求返回非 200,我不希望它中断其他请求。
  • 所有请求都在不同的域上...(所以我不确定这如何适合设置base_uri...

如果所有 5 个请求都返回 200OK < 500ms,那么我希望能够循环遍历它们的响应...

但是,如果说其中 2 个非 200,其中 1 个超时(超过 500 毫秒),我希望仍然能够访问 2 个成功的响应。

编辑到目前为止,除了超时仍然引发异常之外,一切正常

这是我到目前为止所拥有的:

<?php

  require __DIR__.'/../vendor/autoload.php';

  use GuzzleHttp\Client;
  use GuzzleHttp\Promise;

  $client = new Client([
    'http_errors'     => false,
    'connect_timeout' => 1.50, //////////////// 0.50
    'timeout'         => 2.00, //////////////// 1.00
    'headers' => [
      'User-Agent' => 'Test/1.0'
    ]
  ]);

  // initiate each request but do not block
  $promises = [
    'success'            => $client->getAsync('https://httpbin.org/get'),
    'success'            => $client->getAsync('https://httpbin.org/delay/1'),
    'failconnecttimeout' => $client->getAsync('https://httpbin.org/delay/2'),
    'fail500'            => $client->getAsync('https://httpbin.org/status/500'),
  ];

  // wait on all of the requests to complete. Throws a ConnectException if any
  // of the requests fail
  $results = Promise\unwrap($promises);

  // wait for the requests to complete, even if some of them fail
  $results = Promise\settle($promises)->wait();
Run Code Online (Sandbox Code Playgroud)

use*_*068 8

Guzzle在泳池中提供fulfilled和回调。rejected在这里,我根据您的值进行了测试,请在Guzzle 文档中阅读更多内容:

    $client = new Client([
        'http_errors'     => false,
        'connect_timeout' => 0.50, //////////////// 0.50
        'timeout'         => 1.00, //////////////// 1.00
        'headers' => [
          'User-Agent' => 'Test/1.0'
        ]
      ]);

$requests = function ($total) {
    $uris = [
        'https://httpbin.org/get',
        'https://httpbin.org/delay/1',
        'https://httpbin.org/delay/2',
        'https://httpbin.org/status/500',
        ];
    for ($i = 0; $i < count($uris); $i++) {
        yield new Request('GET', $uris[$i]);
    }
};

$pool = new Pool($client, $requests(8), [
    'concurrency' => 10,
    'fulfilled' => function ($response, $index) {
        // this is delivered each successful response
        print_r($index."fulfilled\n");
    },
    'rejected' => function ($reason, $index) {
        // this is delivered each failed request
        print_r($index."rejected\n");
    },
]);
// Initiate the transfers and create a promise
$promise = $pool->promise();
// Force the pool of requests to complete.
$promise->wait();
Run Code Online (Sandbox Code Playgroud)

回复

0fulfilled
3fulfilled
1rejected
2rejected
Run Code Online (Sandbox Code Playgroud)

如果您想使用上面的代码,您还可以在 $promises 中传递响应状态,这是一个示例:

use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
....
$client = new Client([
    'http_errors'     => false,
    'connect_timeout' => 1.50, //////////////// 0.50
    'timeout'         => 2.00, //////////////// 1.00
    'headers' => [
      'User-Agent' => 'Test/1.0'
    ]
  ]);

            $promises = [
        'success' => $client->getAsync('https://httpbin.org/get')->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . "\n";
            },
            function (RequestException $e) {
                echo $e->getMessage() . "\n";
                echo $e->getRequest()->getMethod();
            }
        )
        ,
        'success' => $client->getAsync('https://httpbin.org/delay/1')->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . "\n";
            },
            function (RequestException $e) {
                echo $e->getMessage() . "\n";
                echo $e->getRequest()->getMethod();
            }
        ),
        'failconnecttimeout' => $client->getAsync('https://httpbin.org/delay/2')->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . "\n";
            },
            function (RequestException $e) {
                echo $e->getMessage() . "\n";
                echo $e->getRequest()->getMethod();
            }
        ),
        'fail500' => $client->getAsync('https://httpbin.org/status/500')->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . "\n";
            },
            function (RequestException $e) {
                echo $e->getMessage() . "\n";
                echo $e->getRequest()->getMethod();
            }
        ),
      ];

  $results = Promise\settle($promises)->wait();
Run Code Online (Sandbox Code Playgroud)