La manipulation de Savon délais d'attente en PHP
Je travaille sur un projet où je suis la vérification des informations d'un utilisateur avec un web service SOAP. Je suis actuellement en prenant soin d'erreurs en supposant que je suis la réception des réponses du service web, mais aussi besoin de gérer les cas de bord d'un service de délai d'attente ou de l'indisponibilité.
Dans le cas d'un dépassement de délai ou d'indisponibilité du service, j'ai besoin de faire semblant que la demande a été couronnée de succès (que le service web a approuvé l'info), mais je ne suis pas clair sur ce que les exceptions sont levées.
De pseudo-code:
//$client is PHP's SoapClient class
try {
$response = $client->SomeSoapRequest();
}
catch(SoapFault $e){
//handle issues returned by the web service
}
catch(Exception $e){
//handle PHP issues with the request
}
Ce que je n'arrive pas à trouver est:
- Sont les délais d'attente d'un
SoapFault
? Si oui, quelle est la meilleure façon de distinguer entre, d'une erreur de dépassement de délai et de service web de questions (comme une erreur de type, etc.)? J'ai trouvé une page qui parle d'une erreur où le message a été quelque chose à l'effet de "Erreur de chargement des en-têtes", mais ne mentionne pas si c'était une erreur Soap. - Comment est un service de l'indisponibilité potentiellement va arriver? Une exception en PHP me semble qu'il serait logique (un type soapfault serait retourné par le service web où l'indisponibilité serait un problème de socket ou similaire)?
- Est-il un service existant (par exemple exemple) que je peux tester un délai d'attente contre? La plupart des dépassement de délai lié discussions semblent être liées à la prévention des délais d'attente en étendant la valeur par défaut paramètre de délai d'attente, ce qui n'est pas l'idéal dans cette situation.
- Jamais vous résoudre ce problème?
- Pas vraiment. Je n'ai pas encore essayer Robert Ludwick de la solution, mais il me semble que la chose la plus proche de ce dont j'ai besoin. Si vous trouvez la solution qui fonctionne (ou un autre qui n'), s'il vous plaît laissez-moi savoir!
- Toujours pas de solution? 🙁
- Découvrez ma réponse. Ne pouvais pas trouver une solution affiché nulle part. Codé de ce que devrait être une solution complète pour étendre SoapClient et de remplacer son
__doRequest()
méthode.
Vous devez vous connecter pour publier un commentaire.
1) En cas de timeout, PHP lève une exception de type soapfault avec
faultcode="HTTP"
etfaultstring="Error Fetching http headers"
.2) À mon avis, la meilleure façon de distinguer entre, d'une erreur de dépassement de délai et de service web de questions c'est en regardant le
faultcode
etfaultstring
membres de la Type soapfault classe.En particulier, la
faultcode
élément est conçu pour être utilisé par le logiciel afin de fournir un algorithme mécanisme pour identifier la panne.Comme vous pouvez le lire dans un commentaire sur le manuel PHP, il n'y a pas de méthode pour lire les
faultcode
de la propriété, de sorte que vous avez à y accéder directement (par exemple.$e->faultcode
), parce que legetCode()
méthode ne fonctionne pas.Le SOAP 1.1 Spec définit quatre valeurs possibles pour la
faultcode
champ:En plus de ces codes, PHP utilise le
HTTP
code pour identifier les erreurs qui se passe au niveau du protocole (par exemple.: erreurs de socket); par exemple, si vous recherchezadd_soap_fault
dans le ext/soap/php_http.c code source, vous pouvez voir si certains de ces types de défauts sont générés.Par la recherche de la
add_soap_fault
etsoap_server_fault
fonctions dans le PHP SAVON source de l'extension des fichiers, j'ai construit la liste suivante de PHPSoapFault
exceptions:3) afin De simuler la condition de délai d'attente, essayez avec le code suivant:
soapclient.php
soapserver.php
Avis de la
sleep
appel dans leSoapServer.php
script avec l'heure (20) plus long que le temps (10) spécifiée pour l'default_socket_timeout
paramètre dans laSoapClient.php
script.Si vous souhaitez simuler un service d'indisponibilité, vous pouvez par exemple changer le
location
protocole dehttp
àhttps
dans lesoapclient.php
script, en supposant que votre serveur web n'est pas configuré pour le protocole SSL, et, ce faisant, PHP doit lancer une "impossible de se connecter à l'hôte" de type soapfault.__doRequest()
méthode afin de permettre de fixer le délai d'attente du socket pour un seul SoapClient.Ressemble
default_socket_timeout
n'est pas pris en compte lors de la prise des appels SOAP sur HTTPS:Bug ouvert au moment de l'écriture. Comme un commentaire sur le blog de Robert Ludwick référencé supprimé réponse temporisation PHP Appels Soap (21 Oct 2009; Publiés par Robert F. Ludwick), la solution de contournement le poste de traite (en ignorant
SoapClient::__doRequest()
avec une demande curl) travaille autour de ce bug aussi.Un autre problème est:
Le code mentionné dans le billet de blog a subi quelques modifications et peut être trouvé dans sa forme la plus récente, avec le soutien de l'authentification HTTP, ici, sur Github:
Dans tous les cas, la solution ne devrait pas être nécessaire plus longtemps que ce problème a été corrigé dans le PHP SOAPClient extension.
default_socket_timeout
devrait travailler avec ssl maintenant.Pour faire face aux délais d'attente dans le service
De mon expérience, si
$e->getMessage
est "Erreur de Récupérer les en-têtes http", vous avez affaire à un délai d'attente réseau.Si
$e->getMessage
est quelque chose comme "Ne peut pas se connecter à l'hôte", le service que vous essayez d'atteindre est vers le bas.Il y a ensuite "il Semble que nous n'avons aucune document XML", qui est plus cryptique un peut signifier différentes choses.
J'ai utilisé deux facteurs pour obtenir mon SoapClient de l'extension de jeter une belle exception. Le message et le moment où la demande a eu pour revenir. Je pense que le message d'erreur "Erreur de Récupérer les en-têtes http" peut également se produire dans certains autres cas, donc le temps de vérifier.
Le code suivant doit être sujet de droit
Je puis utiliser SoapClientWithTimeout
Pour déboguer votre service à l'expiration du délai. Ajoutez la ligne suivante avant d'appeler le service
Simplement le réglage de la
default_socket_timeout
à l'échelle mondiale via l'ini ne peut pas faire ce que vous voulez. Cela aurait un impact sur les requêtes SOAP, mais aussi affecter d'autres connexions sortantes, y compris DB connexions. Au lieu de cela, remplacer SoapClient de l' __doRequest() méthode pour faire de la connexion HTTP vous-même. Vous pouvez ensuite configurer votre propre timeout sur la socket, détecter, et de lancer des exceptions que vous pouvez intercepter et gérer.Suppose que je suis en peu en retard, mais au cas où quelqu'un est toujours à la recherche de solution à des délais d'attente en php client soap - voici ce qui a fonctionné pour moi:
De manière générale, en remplacement de PHP SoapClient avec cURL avec temporisation. Il suffit de garder à l'esprit, parfois WS attend action spécifiée dans l'en-tête HTTP. Solution originale, affichés sur ce site ne comprennent pas que (observations).
suffit d'utiliser le "stream_context" pour régler le paramètre de délai d'attente aussi pour WSDL chargement (vous devez définir la SoapClient $options['connection_timeout']) avant: