2013-10-22 17 views
16

मैं गुज़ल का उपयोग करके एकल अनुरोध कर सकता हूं और अब तक मैं गुज़ल के प्रदर्शन से बहुत खुश हूं, हालांकि, मैंने गुज़ल एपीआई में मल्टीकर्ल और बैचिंग के बारे में कुछ पढ़ा है।एक ही समय में एकाधिक Guzzle अनुरोध कैसे करें?

क्या कोई मुझे बता सकता है कि एक ही समय में एकाधिक अनुरोध कैसे करें? यदि संभव हो तो Async। मुझे नहीं पता कि मल्टीकर्ल के साथ उनका क्या मतलब है। सिंक भी एक समस्या नहीं होगी। मैं सिर्फ एक ही समय में बहुत करीब या बहुत करीब (समय की छोटी जगह) करना चाहता हूं।

+0

दस्तावेज़ों में एक [डेमो] (http://guzzlephp.org/http-client/client.html#sending-requests-in-parallel) है। यह अभी भी आपके परिप्रेक्ष्य से एक तुल्यकालिक कॉल है, लेकिन आंतरिक रूप से समानांतर होगा - इस प्रकार कॉल के लिए कुल समय केवल सबसे लंबे समय तक पहुंचने का समय होगा। – halfer

उत्तर

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

: http://guzzle3.readthedocs.org/http-client/client.html#sending-requests-in-parallel

एक आसान समाधान है कि रिटर्न अनुरोध के हैश एक प्रतिक्रिया या त्रुटि के मानचित्रण वस्तुओं का उपयोग करने के लिए, http://guzzle3.readthedocs.org/batching/batching.html#batching

कम उदाहरण देखने नए GuzzleHttp guzzlehttp/guzzle

से संबंधित एक अद्यतन

समवर्ती/समानांतर कॉल अब .. RequestInterfaces की एक सरणी गुजर अब काम नहीं करेगा के पुराने तरीके से वादे सहित कुछ भिन्न तरीकों के माध्यम से चलाए जा रहे हैं Concurrent Requests

यहाँ उदाहरण

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

अद्यतन देखें: के रूप में टिप्पणी में सुझाव दिया और @ संकल्प-तांबे से पूछा, आप भी से बचने के लिए एक अलग दृष्टिकोण का उपयोग कर सकते हैं कि एक साथ समवर्ती अनुरोध का एक सेट विफलता सभी प्रतिक्रियाओं को वापस नहीं करेगा।

पूल के साथ सुझाए गए विकल्प व्यवहार्य हैं, लेकिन मैं अभी भी वादे पसंद करता हूं।

वादे के साथ एक उदाहरण निपटान का उपयोग करना और अनचाहे के बजाय विधियों का इंतजार करना है।

उदाहरण से अंतर से ऊपर होगा

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

मैं कैसे $ प्रतिक्रियाएं भी संभाल करने पर संदर्भ के लिए नीचे एक पूर्ण उदाहरण बनाया है।

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 
} 

इस उदाहरण कोड मूल रूप से here तैनात थे।

+0

हालांकि यह कई छवियों के डेटा को एक बार में लोड करने के मेरे उपयोग के मामले में बहुत अच्छा काम करता है, फिर भी कोई ऐसी स्थिति को कैसे संभाला जा सकता है जहां URL में से एक लोड हो रहा है 404 त्रुटि फेंकता है? जब ऐसा होता है, तो गुज़ल बाहर निकलता है और एक गोज़ अपवाद फेंकता है। मैं यूआरएल की उपलब्धता की गारंटी नहीं दे सकता, इसलिए मैं केवल कई अनुरोधों को लोड करने और उन लोगों का उपयोग करने की उम्मीद कर रहा था जो वास्तव में गुजरते हैं। – georaldc

+0

कभी नहीं, मैंने इसके बजाय GuzzleHttp \ Pool का उपयोग करने के लिए अपना कोड दोबारा किया। अच्छी तरह से काम करने लगता है और मुझे थोड़ा और नियंत्रण देता है। – georaldc

+1

क्या आप पूल के साथ एकाधिक यूआरएल के लिए अपना कोड साझा कर सकते हैं। –

संबंधित मुद्दे