Vil*_*lx- 3 php asynchronous guzzle
我需要编写一个可以向外部服务发送许多 HTTP 请求的处理器。由于我想最大限度地提高性能,因此我希望最大限度地减少阻塞。我正在使用 PHP 5.6 和 GuzzleHTTP。
GuzzleHTTP 确实有一个异步请求选项。但由于 PHP 中只有 1 个可用线程,我需要分配一些时间来处理它们。不幸的是,我只看到一种方法 - 调用waitwhich 块,直到所有请求都得到处理。那不是我想要的。
相反,我想要一些方法来处理已经到达的内容,然后返回。这样我就可以做一些类似的事情:
$allRequests = [];
while ( !checkIfNeedToEnd() ) {
$newItems = getItemsFromQueue();
$allRequests = $allRequests + spawnRequests($newItems);
GuzzleHttp::processWhatYouCan($allRequests);
removeProcessedRequests($allRequests);
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?
好吧...我自己想出来了:
$handler = new \GuzzleHttp\Handler\CurlMultiHandler();
$client = new \GuzzleHttp\Client(['handler' => $handler]);
$promise1 = $client->getAsync("http://www.stackoverflow.com");
$promise2 = $client->getAsync("http://localhost/");
$doneCount = 0;
$promise1->then(function() use(&$doneCount) {
$doneCount++;
echo 'Promise 1 done!';
});
$promise2->then(function() use(&$doneCount) {
$doneCount++;
echo 'Promise 2 done!';
});
$last = microtime(true);
while ( $doneCount < 2 ) {
$now = microtime(true);
$delta = round(($now-$last)*1000);
echo "tick($delta) ";
$last = $now;
$handler->tick();
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
勾选(0) 勾选(6) 勾选(1) 勾选(0) 勾选(1001) 勾选(10) 勾选(96) 承诺2 完成!勾选(97) 承诺1 完成!
神奇的成分是创造CurlMultiHandler你自己,然后tick()在方便的时候召唤它。之后就如往常一样许诺了。如果队列为空,则tick()立即返回。
请注意,如果没有活动,它仍然可以阻塞最多 1 秒(默认)。如果需要,也可以更改:
$handler = new \GuzzleHttp\Handler\CurlMultiHandler(['select_timeout' => 0.5]);
Run Code Online (Sandbox Code Playgroud)
该值以秒为单位,但具有浮点数。