soapclient cliente php web-services timeout soap-client

cliente - PHP SoapClient Timeout



soap 1.2 php (6)

Estoy usando la siguiente lógica cuando trabajo con SOAPClient:

public function executeSoapCall($method, $params) { try { $client = $this->tryGetSoapClient(); $timeout = ini_get(''default_socket_timeout''); ini_set(''default_socket_timeout'', 60);//set new timeout value - 60 seconds $client->__soapCall($method, $params);//execute SOAP call ini_set(''default_socket_timeout'', $timeout);//revert timeout back } catch (/Throwable $e) { if (isset($timeout)) { ini_set(''default_socket_timeout'', $timeout);//revert timeout back } } } protected function tryGetSoapClient() { $timeout = ini_get(''default_socket_timeout'');//get timeout (need to be reverted back afterwards) ini_set(''default_socket_timeout'', 10);//set new timeout value - 10 seconds try { $client = new /SoapClient($this->wsdl, $this->options);//get SOAP client } catch (/Throwable $e) { ini_set(''default_socket_timeout'', 10);//revert back in case of exception throw $e; } $this->iniSetTimeout($timeout);//revert back return $client; }

Esto me ayuda a esperar hasta 10 segundos para el establecimiento de la conexión y 60 segundos para la ejecución de la llamada.

¿Hay alguna forma para que una solicitud de SoapClient agote el tiempo de espera y lance una excepción? A partir de ahora, tengo un tiempo de espera de respuesta del servidor PHP, en mi caso 60 segundos. Básicamente, lo que quiero es que, si no hay ninguna respuesta del Servicio Web dentro de cierto tiempo, se lanzará una excepción y podría detectarla. La advertencia de 60 segundos no es lo que quiero.


La respuesta aceptada romperá todas las funcionalidades que SoapClient tiene para ofrecer. Como configurar los encabezados de contenido correctos, autenticación, etc.

Esta sería una mejor solución al problema.

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; } }


Mira esto

Si te sientes cómodo y tu entorno te permite extender las clases.

Básicamente, extiende la clase SoapClient , reemplaza el transporte HTTP con curl que puede manejar los tiempos de espera:

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



Si bien Andrei se vinculó a una solución decente, este tiene menos código pero llega a una buena solución:

Código de ejemplo:

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

Y también está el contexto de la transmisión, si necesita un control HTTP más detallado. Vea la opción stream_context para los new SoapClient() . Bajo la superficie, SoapClient utiliza los transportes HTTP y SSL.


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

La opción connection_timeout define un tiempo de espera en segundos para la conexión al servicio SOAP. Esta opción no define un tiempo de espera para servicios con respuestas lentas. Para limitar el tiempo de espera para que las llamadas finalicen, está disponible la configuración default_socket_timeout.