2013-10-22 27 views
16

Guzzle kullanarak tek istekte bulunabilirim ve Guzzle'un performansından çok memnunum, ancak Guzzle API'sinde MultiCurl ve Batching hakkında bir şeyler okudum.Aynı anda birden çok Ağızlık isteği nasıl yapılır?

Birisi bana aynı anda birden fazla istekte bulunmayı nasıl açıklayabilir? Mümkünse MultiCurl ile ne demek istediklerini bilmiyorum. Senkronizasyon da sorun olmaz. Sadece aynı anda veya çok yakın birden fazla istek yapmak istiyorum (zamanın kısa bir süre). Dokümanlar

+0

Dokümanlarda bir [demo] var (http://guzzlephp.org/http-client/client.html#sending-requests-in-parallel). Bu sizin perspektifinizden hala senkronize bir çağrıdır, ancak dahili olarak paralel olacaktır - dolayısıyla, çağrının toplam süresi sadece en uzun getirme zamanı olacaktır. – halfer

cevap

18

:

<?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') 
)); 
16

: kolay bir isteğin karma bir yanıt veya hata eşleştirmesini nesneleri döndürür çözümü kullanabilmesi için http://guzzle3.readthedocs.org/http-client/client.html#sending-requests-in-parallel

, http://guzzle3.readthedocs.org/batching/batching.html#batching

Kısa örneğe bakın Yeni GuzzleHttp guzzlehttp/guzzle

ile ilgili güncelleme

Eşzamanlı/paralel çağrılar artık Concurrent Requests

.. Promises dahil olmak üzere birkaç farklı yöntemlerle artık işe yaramaz RequestInterfaces bir dizi geçirerek eski yöntemi çalıştırılır.

burada örnek

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

Güncelleme bakınız: Yorum önerilen ve @ Sankalp-tambe tarafından sorulan gibi , ayrıca önlemek için farklı bir yaklaşım kullanabileceği bir ile eşzamanlı istek bir dizi başarısızlık tüm cevapları geri vermez.

Havuz ile önerilen seçenekler mümkün olsa da, hala sözünü tercih ediyorum.

Sözlerle ilgili bir örnek, yerleşimi kullanmak ve paketini açmak yerine bekletme yöntemlerini kullanmaktır.

örnekten farkı yukarıdaki

$responses = \GuzzleHttp\Promise\settle($requestArr)->wait(); 

olacağını ben de $ yanıtları işlemek için nasıl başvuru için aşağıdaki tam bir örnek oluşturduk.

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 
} 

Bu örnek kod

aslen here gönderilmiş.

+0

Bu, birden çok resim URL'sinin verilerini bir kerede yüklememe durumum için harika olsa da, yüklenen URL'lerden birinin bir 404 hatası attığı bir durumu nasıl ele alabilirim? Bu olduğunda, Guzzle çıldırdı ve bir namlu istisnası atar. URL'lerin kullanılabilirliğini garanti edemem, bu yüzden birden fazla istek yüklemeyi ve aslında içinden geçenleri kullanmayı umuyordum. – georaldc

+0

Nevermind, kodumu GuzzleHttp \ Pool kullanmak için yeniden yaptım. İyi çalışıyor ve bana biraz daha kontrol sağlıyor. – georaldc

+1

Kodunuzu, birden çok URL için Pool ile paylaşabilirsiniz. –

İlgili konular