php - guzzlehttp - ¿Cómo realizar múltiples solicitudes de Guzzle al mismo tiempo?
guzzlehttp query (2)
De los documentos: http://guzzle3.readthedocs.org/http-client/client.html#sending-requests-in-parallel
Para una solución fácil de usar que devuelve un hash de objetos de solicitud asignados a una respuesta o error, consulte http://guzzle3.readthedocs.org/batching/batching.html#batching
Ejemplo corto:
<?php
$client->send(array(
$client->get(''http://www.example.com/foo''),
$client->get(''http://www.example.com/baz''),
$client->get(''http://www.example.com/bar'')
));
Puedo realizar solicitudes individuales utilizando Guzzle y estoy muy satisfecho con el rendimiento de Guzzle hasta ahora, sin embargo, leí en la API de Guzzle algo sobre MultiCurl y Batching.
¿Podría alguien explicarme cómo hacer múltiples solicitudes al mismo tiempo? Async si es posible. No sé si eso es lo que quieren decir con MultiCurl. La sincronización tampoco sería un problema. Solo quiero hacer varias solicitudes al mismo tiempo o muy cerca (poco tiempo).
Una actualización relacionada con el nuevo GuzzleHttp guzzlehttp / guzzle
Las llamadas simultáneas / paralelas ahora se ejecutan a través de varios métodos diferentes, que incluyen promesas. Solicitudes concurrentes
La antigua forma de pasar una matriz de RequestInterfaces ya no funcionará.
Ver ejemplo aquí
$newClient = new /GuzzleHttp/Client([''base_uri'' => $base]);
foreach($documents->documents as $doc){
$params = [
''language'' =>''eng'',
''text'' => $doc->summary,
''apikey'' => $key
];
$requestArr[$doc->reference] = $newClient->getAsync( ''/1/api/sync/analyze/v1?'' . http_build_query( $params) );
}
$time_start = microtime(true);
$responses = /GuzzleHttp/Promise/unwrap($requestArr); //$newClient->send( $requestArr );
$time_end = microtime(true);
$this->get(''logger'')->error('' NewsPerf Dev: took '' . ($time_end - $time_start) );
Actualización : Tal como se sugiere en los comentarios y lo solicita @ sankalp-tambe, también puede utilizar un enfoque diferente para evitar que un conjunto de solicitudes concurrentes con un error no devuelva todas las respuestas.
Si bien las opciones sugeridas con Pool son factibles, sigo prefiriendo promesas.
Un ejemplo con promesas es usar métodos de liquidación y espera en lugar de desenvolver.
La diferencia con el ejemplo anterior sería
$responses = /GuzzleHttp/Promise/settle($requestArr)->wait();
He creado un ejemplo completo a continuación como referencia sobre cómo manejar las $ respuestas también.
require __DIR__ . ''/vendor/autoload.php'';
use GuzzleHttp/Client as GuzzleClient;
use GuzzleHttp/Promise as GuzzlePromise;
$client = new GuzzleClient([''timeout'' => 12.0]); // see how i set a timeout
$requestPromises = [];
$sitesArray = SiteEntity->getAll(); // returns an array with objects that contain a domain
foreach ($sitesArray as $site) {
$requestPromises[$site->getDomain()] = $client->getAsync(''http://'' . $site->getDomain());
}
$results = GuzzlePromise/settle($requestPromises)->wait();
foreach ($results as $domain => $result) {
$site = $sitesArray[$domain];
$this->logger->info(''Crawler FetchHomePages: domain check '' . $domain);
if ($result[''state''] === ''fulfilled'') {
$response = $result[''value''];
if ($response->getStatusCode() == 200) {
$site->setHtml($response->getBody());
} else {
$site->setHtml($response->getStatusCode());
}
} else if ($result[''state''] === ''rejected'') {
// notice that if call fails guzzle returns is as state rejected with a reason.
$site->setHtml(''ERR: '' . $result[''reason'']);
} else {
$site->setHtml(''ERR: unknown exception '');
$this->logger->err(''Crawler FetchHomePages: unknown fetch fail domain: '' . $domain);
}
$this->entityManager->persist($site); // this is a call to Doctrines entity manager
}
Este código de ejemplo fue publicado originalmente here .