2010-10-14 9 views
0

Je rencontre un problème sporadique avec l'option RETURNTRANSFER de curl. Je ne suis pas sûr si j'ai oublié quelque chose dans mon code qui le cause, ou si ce n'est pas bien documenté et que je ne suis pas au courant du fonctionnement de RETURNTRANSFER. J'utilise curl (via php) pour envoyer des données XML via POST à ​​un programme d'écoute externe. En cas de succès, l'écouteur répond et renvoie le même xml, avec un ou deux champs remplis que j'ai envoyés à travers vide. par ex. <Status /> devient <Status> Accepté </Status>. Une taille approximative du POST xml complet - [upload_content_length] => 1414. Un ID unique (généré de mon côté) est envoyé, si l'auditeur reçoit un ID en double, il décline les données XML et répond par un message d'erreur en texte brut.Courbe RETURNTRANSFER données? problème et plusieurs POST identiques

Cela fonctionne 99,9% du temps.

Le code boucle est:

$header[] = "Content-Type: text/xml"; 
$header[] = "Content-length: ".strlen($post_string); 
$x = curl_init("https://xyz.com"); 
curl_setopt($x, CURLOPT_HEADER, 0); 
curl_setopt($x, CURLOPT_HTTPHEADER, $header); 
curl_setopt($x, CURLOPT_POST, 1); 
curl_setopt($x, CURLOPT_POSTFIELDS,$xmldata); 
curl_setopt($x, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($x, CURLOPT_REFERER, "https://mypage.com"); 
curl_setopt($x, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($x, CURLOPT_PORT, 443); 
curl_setopt($x, CURLOPT_SSL_VERIFYPEER, 0); //to allow self-signed SSL cert 
curl_setopt($x, CURLOPT_SSL_VERIFYHOST, 0); //to allow self-signed SSL cert 
curl_setopt($x, CURLOPT_TIMEOUT, 30); 
curl_setopt($x, CURLOPT_FORBID_REUSE, TRUE); 
curl_setopt($x, CURLOPT_FRESH_CONNECT, TRUE); 
curl_setopt($x, CURLOPT_BUFFERSIZE, 64000); 
curl_setopt($x, CURLOPT_VERBOSE, 1); 
$listenerresponse = curl_exec($x); 
$info = curl_getinfo($x); 
curl_close($x); 

Récemment, je suis ramasser des erreurs où les erreurs d'écoute sur ID en double.

Mes journaux indiquent la chronologie que ce ::

  1. Flexion de l'ID unique "12345678"

  2. auditeur répond "ID en double" à 2010-10-13 17:27:59

  3. écouteur répond "accepté" 2010-10-13 17:28:06

Au départ, je pensais qu'un ID précédent avait été mis en cache d'une manière ou d'une autre et était envoyé de manière erronée, mais ce n'est pas le cas. L'écouteur reçoit l'ID correct. Les journaux d'écoute le montrent l'inverse, avec une chronologie légèrement différente:

  1. Listener répond "Accepté" à 2010-10-13 17:27:48

  2. Listener répond « ID en double «Je à 2010-10-13 17:27:58

de ma compréhension, attendez-vous le fil boucle d'attendre la réponse, et ne pas envoyer une autre demande. Ai-je raison de supposer que le problème est lié au réseau - les paquets possibles sont-ils perdus/quelque chose de similaire? Toutes les suggestions sur la façon d'éviter que cela se produise seraient très appréciées. Idéalement, je voudrais rouler pour envoyer et attendre la réponse complète avant d'envoyer une autre demande ... Y at-il une option pour spécifier cela? S'il vous plaît aider :-)

Merci pour votre attention.

S.

Répondre

1

Par CURL par défaut bloqueront (par exemple attente) pour une demande de remplir avant de retourner de la curl_exec() ca. . Vous ne semblez pas utiliser multi-curl (qui permet plusieurs requêtes parallèles), donc il ne devrait pas y avoir de moyen pour qu'un paquet de la requête A soit mélangé avec des paquets de la requête B, C, ... A va se terminer et retourner avant que la requête B ne soit déclenchée.

Avez-vous le contrôle du script d'écouteur? Vous pouvez inclure un jeton que vous générez avec chaque requête, en plus de ce paramètre "unique", et l'écouter dans les messages d'erreur, afin que vous puissiez déterminer exactement quelle requête a provoqué les erreurs d'ID en double.

+0

Malheureusement je n'ai aucun contrôle sur l'auditeur. Je pensais la même chose que ce que vous avez dit - une seule demande et attendre, j'ai délibérément évité toute multi curling. Voyant la durée entre le départ et l'arrivée (et que le Declined me revient avant l'Accepted), pourrait-il y avoir une réponse TCP que curl interprète comme un signal pour renvoyer la requête? –

+0

Ça ne devrait pas. CURL general ne se préoccuperait pas des trucs de niveau TCP, juste du HTTP de plus haut niveau. Si vous avez un accès shell au serveur, vous pouvez essayer de voir la sortie 'netstat' et voir combien de connexions sont faites, ou mieux encore, si vous avez un accès root, utilisez un renifleur de paquets pour surveiller les communications. –