[英]How to perform concurrent requests with GuzzleHttp
我如何使用 Guzzle 6 创建具有以下条件的 5 个异步请求:
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();
Guzzle在池中提供已fulfilled
和已rejected
callabcks。 在这里,我根据您的值进行了测试,请参阅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();
响应
0fulfilled
3fulfilled
1rejected
2rejected
如果您想使用上面的代码,也可以在$ 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();
对于并发发送多个 https 请求,那么您可以按如下方式进行
请参阅下面的示例代码
<?php
$client = new \GuzzleHttp\Client(['base_uri' => 'http://test.com']);
$requests = function () use ($client, $product) {
foreach ($product as $val) {
$methodType = $val['method_type']; // Get, Post, Put
$urlPath = $val['url_path']; // url path eg. /search/car/{abc}
$payload = json_decode($val['payload'], true); // your data if you wish to send in request
yield function() use ($client, $methodType, $urlPath) {
return $client->requestAsync($methodType, $urlPath, []);
// return $client->requestAsync($methodType, $urlPath, [\GuzzleHttp\RequestOptions::JSON => $payload]); // for send data as a Json
// return $client->requestAsync($methodType, $urlPath, [\GuzzleHttp\RequestOptions::QUERY => $payload]); // for send data as a Query String in url
};
}
};
$pool = new \GuzzleHttp\Pool($client, $requests(), [
'concurrency' => 3,
'fulfilled' => function (Response $response, $index) use (&$responses, &$successCount) {
if ($response->getStatusCode() == 200) {
// http status ok response
$responses[] = json_decode($response->getBody(), true);
$successCount++;
} else {
// do perform your logic for success response without 200 HTTP Status code
}
},
'rejected' => function (\GuzzleHttp\Exception\RequestException $reason, $index) use (&$failedCount) {
// error response handle here
if ($reason->hasResponse()) {
$response = $reason->getResponse();
$httpstatuscode = $response->getStatusCode();
}
Log::error($reason->getMessage());
$failedCount++;
},
]);
$pool->promise()->wait();
var_dump($responses);
更详细的见这里
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.