2010-08-17 22 views
19

क्या सोप क्लाइंट अनुरोध के लिए वैसे भी कोई अपवाद है और अपवाद फेंकना है। अभी तक, मुझे अपने मामले 60 सेकंड में PHP सर्वर प्रतिक्रिया टाइमआउट मिलता है। असल में मैं क्या चाहता हूं, अगर किसी समय के भीतर वेब सेवा से कोई जवाब नहीं है, तो एक अपवाद फेंक दिया जाएगा और मैं इसे पकड़ सकता हूं। 60 सेकंड की चेतावनी वह नहीं है जो मैं चाहता हूं।PHP सोप क्लाइंट टाइमआउट

उत्तर

16

यदि आप सहज महसूस करते हैं और अपने पर्यावरण आप कक्षाओं का विस्तार करने की अनुमति देता है

पर एक नज़र डालें।

यह मूल रूप से, SoapClient वर्ग फैली की जगह कर्ल के साथ HTTP परिवहन जो समय समाप्ति संभाल कर सकते हैं:

class SoapClientTimeout extends SoapClient 
{ 
    private $timeout; 

    public function __setTimeout($timeout) 
    { 
     if (!is_int($timeout) && !is_null($timeout)) 
     { 
      throw new Exception("Invalid timeout value"); 
     } 

     $this->timeout = $timeout; 
    } 

    public function __doRequest($request, $location, $action, $version, $one_way = FALSE) 
    { 
     if (!$this->timeout) 
     { 
      // Call via parent because we require no timeout 
      $response = parent::__doRequest($request, $location, $action, $version, $one_way); 
     } 
     else 
     { 
      // Call via Curl and use the timeout 
      $curl = curl_init($location); 

      curl_setopt($curl, CURLOPT_VERBOSE, FALSE); 
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
      curl_setopt($curl, CURLOPT_POST, TRUE); 
      curl_setopt($curl, CURLOPT_POSTFIELDS, $request); 
      curl_setopt($curl, CURLOPT_HEADER, FALSE); 
      curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); 
      curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout); 

      $response = curl_exec($curl); 

      if (curl_errno($curl)) 
      { 
       throw new Exception(curl_error($curl)); 
      } 

      curl_close($curl); 
     } 

     // Return? 
     if (!$one_way) 
     { 
      return ($response); 
     } 
    } 
} 
+0

धन्यवाद करने के लिए एक बेहतर समाधान हो जाएगा। यह देखने के लिए एक जगह होगी। चलिए देखते हैं कि कोई अन्य है या नहीं। –

+2

मैंने PHP 5.4.6 में यह कोशिश की है, लेकिन ऐसा लगता है कि उन्होंने बिना किसी सूचना के '_doRequest()' के हस्ताक्षर को बदल दिया है। '$ अनुरोध' में अब कच्चे एक्सएमएल नहीं हैं, बल्कि' 141201299690460051141201717499383133141201717499423132141201717499443131141201717499463131141201717499483135false' जैसी स्ट्रिंग नहीं है। क्या कोई इस पर रोशनी डाल सकता है? –

+0

यह साबुन क्लाइंट के पूरे आंतरिक तोड़ देगा। –

44

आंद्रेई एक सभ्य समाधान से जुड़ा हुआ है, इस एक अभी तक कम कोड है एक अच्छा समाधान पर आता है:

उदाहरण कोड:

0,123,
// 
// setting a connection timeout (fifteen seconds on the example) 
// 
$client = new SoapClient($wsdl, array("connection_timeout" => 15)); 

और यदि आपको अधिक बढ़िया HTTP नियंत्रण की आवश्यकता है, तो स्ट्रीम संदर्भ भी है। new SoapClient()Docs के लिए stream_context विकल्प देखें। सतह SoapClient के तहत HTTP और SSL ट्रांसपोर्ट का उपयोग करता है।

+1

जब मैं इसका उपयोग करता हूं, मुझे 'अज्ञात SOAP क्लाइंट विकल्प' प्राप्त होता है अपवाद – DanFromGermany

+0

@DanFromGermany, PHP का कौन सा संस्करण आप चल रहे हैं? क्या आप ऊपर दिखाए गए किसी भी विकल्प के अलावा किसी भी विकल्प को पारित कर रहे हैं? –

+1

PHP 5.3, मैं 'साबुन_वर्जन' => SOAP_1_1 भी पास कर रहा हूं, लेकिन मैं 'Zend_Soap_Client' का उपयोग कर रहा हूं, लेकिन यह सिर्फ 'सोप क्लाइंट' – DanFromGermany

28
ini_set("default_socket_timeout", 15); 
$client = new SoapClient($wsdl, array(......)); 

connection_timeout विकल्प सोप सेवा करने के लिए कनेक्शन के लिए सेकंड में एक समय समाप्ति परिभाषित करता है। यह विकल्प धीमी प्रतिक्रिया वाले सेवाओं के लिए टाइमआउट को परिभाषित नहीं करता है। Default_socket_timeout सेटिंग को समाप्त करने के लिए कॉल के लिए प्रतीक्षा करने के लिए समय सीमित करने के लिए।

+0

यह उत्तर है। :) –

+0

जब तक सॉकेट टाइमआउट पार नहीं किया जाता है तब तक यह एक अच्छा जवाब है। अन्यथा सर्वर एक कनेक्शन टाइमआउट फेंक देगा और निष्पादन बंद हो जाएगा ... – Nico

+1

यह भी ध्यान दें कि अभी भी यह अनसुलझा PHP-Bug: https://bugs.php.net/bug.php?id=41631 है। इसलिए 'डिफ़ॉल्ट_socket_timeout' धीमी प्रतिक्रिया के साथ सेवा के लिए HTTPS कनेक्शन –

1

आप संगीतकार के माध्यम से इस स्थापित कर सकते हैं: https://github.com/ideaconnect/idct-soap-client

यह मानक SoapClient प्रदान करता है और विकल्पों पुनर्प्रयास, कनेक्शन की राशि निर्धारित करने और समय समाप्ति को पढ़ने के लिए देता है।

2

स्वीकार्य उत्तर सोप क्लाइंट को प्रदान करने वाली सभी कार्यक्षमताओं को तोड़ देगा। सही सामग्री हेडर,

की स्थापना प्रमाणीकरण आदि की तरह यह समस्या

class MySoapClient extends \SoapClient 
{ 
    private $timeout = 10; 

    public function __construct($wsdl, array $options) 
    { 
     // Defines a timeout in seconds for the connection to the SOAP service. 
     // This option does not define a timeout for services with slow responses. 
     // To limit the time to wait for calls to finish the default_socket_timeout setting is available. 
     if (!isset($options['connection_timeout'])) { 
      $options['connection_timeout'] = $this->timeout; 
     } 

     parent::__construct($wsdl, $options); 
    } 

    public function setTimeout($timeout) 
    { 
     $this->timeout = $timeout; 
    } 

    public function __doRequest($request, $location, $action, $version, $one_way = 0) 
    { 
     $original = ini_get('default_socket_timeout'); 
     ini_set('default_socket_timeout', $this->timeout); 
     $response = parent::__doRequest($request, $location, $action, $version, $one_way); 
     ini_set('default_socket_timeout', $original); 

     return $response; 
    } 

} 
+0

एक अतिरिक्त सुरक्षा नेट के लिए आपको माता-पिता कॉल को आज़माकर/पकड़ना चाहिए (उदाहरण के लिए कुछ ऐप्स/ढांचे एक कस्टम error_handler के माध्यम से चेतावनियों पर अपवाद फेंक सकते हैं) जो अन्यथा अन-रीसेट किए गए 'default_socket_timeout' – staabm

+0

को छोड़ देगा कनेक्शन_टाउटआउट को किसी मान पर डिफ़ॉल्ट होना चाहिए 10secs तो बहुत छोटा है। – staabm

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