2010-02-03 14 views
20

J'écris un service REST simple, qui répond aux demandes des clients. Tout en PHP. Ce qui m'inquiète, c'est que lorsque mon serveur répond à une requête, il peut finir par lier des ressources si le côté client est trop lent à renvoyer une réponse «ok». Comment puis-je envoyer une requête POST via lib_curl en lui demandant de ne pas attendre les réponses, mais de quitter immédiatement après l'envoi des données POST?Envoi de requêtes POST sans attendre de réponse?

Est-ce encore possible? Je vous remercie !

+1

Ce n'est pas le client qui envoie la réponse 200 OK, mais le serveur. Le client fait une requête et le serveur répond, le serveur se fiche de ce qui se passe avec le client (par définition dans REST, il est sans état). Qu'est-ce que vous essayez de faire, pourriez-vous élaborer? – meouw

Répondre

13

Vous ne pouvez pas simplement envoyer des données sans recevoir une réponse avec HTTP. HTTP va toujours demander -> réponse. Même si la réponse est juste très courte (comme un simple 200 sans texte), il doit y avoir une réponse. Et chaque socket HTTP attendra cette réponse.

Si vous ne se soucient pas de la réponse, vous pouvez ajouter un processus au serveur qui fait vos demandes et vous venez pousser vos données de demande à (comme un service qui est en cours d'exécution en arrière-plan, la vérification une base de données de requêtes, et toujours en démarrant la requête chaque fois qu'une nouvelle entrée a été ajoutée). De cette façon, vous effectuerez la requête de manière asynchrone et pourrez quitter dès que vous aurez ajouté cette requête à la pile .

Aussi, comme me l'a dit, le client ne fait partie d'aucune communication que vous faites avec php. Php est un langage côté serveur, donc lorsque le client demande une page Web (le fichier php), le serveur exécute ce fichier (et demande toutes les états du fichier php), puis retourne le résultat au client.

+0

Voilà ce que j'avais besoin de savoir :) Merci – Gotys

+0

@Gotys sidenote, si vous voulez simplement envoyer une "demande" sans attendre une réponse, regardez dans le protocole UDP – chris

+0

Il y a le feu et oubliez "pattern". Une requête asyc lancera la requête. Une fois exécuté, vous pouvez faire autre chose sans attendre. Dans le scénario où vous avez une connexion réseau fiable UDP est une option mais TCP est plus fiable dans la mesure où vous savez que les paquets le feront. Cependant, sans vérifier la réponse, vous ne saurez pas ce qui s'est passé. –

1

Je n'ai jamais essayé cela, mais régler le CURLOPT_TIMEOUT à une valeur très faible pourrait faire l'affaire. Essayez 0 ou 0.1.

Cependant, je ne sais pas comment cURL et le client vont se comporter avec ceci, si la connexion sera activement annulée lorsque la connexion est déjà établie, et le délai d'expiration est atteint. Vous devriez essayer. Si vous appelez des scripts PHP, peut-être que ignore_user_abort() peut vous assurer que vos scripts fonctionnent dans les deux sens.

+2

curl 0 timeout le laisserait fonctionner plus longtemps – Boy

+0

Si vous voulez essayer un temps d'attente bas, utilisez la variation milliseconde curl_setopt ($ curl, CURLOPT_TIMEOUT_MS, 1); –

12

ici:

ob_end_clean(); 
header("Connection: close\r\n"); 
header("Content-Encoding: none\r\n"); 
header("Content-Length: 1"); 
ignore_user_abort(true); 

et la boucle:

curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1); 
curl_setopt($curl, CURLOPT_NOSIGNAL, 1); 
+1

Pourriez-vous expliquer pourquoi cela fonctionne? –

+1

J'ai trouvé plusieurs solutions qui incluaient la partie tampon de sortie mais cela ne fonctionnait toujours pas pour moi jusqu'à ce que j'ajoute ces options de boucle. Merci! –

3

Si vraiment vous ne se soucient pas de la réponse que vous êtes probablement mieux loti exec -ment une commande wget. Ceci est mentionné en passant dans certaines des autres réponses, mais voici une fonction super facile pour envoyer un paquet _POST par cette approche (qui est asynchrone et prend 1-2ms):

function wget_request($url, $post_array, $check_ssl=true) { 

    $cmd = "curl -X POST -H 'Content-Type: application/json'"; 
    $cmd.= " -d '" . json_encode($post_array) . "' '" . $url . "'"; 

    if (!$check_ssl){ 
    $cmd.= "' --insecure"; // this can speed things up, though it's not secure 
    } 
    $cmd .= " > /dev/null 2>&1 &"; //just dismiss the response 

    exec($cmd, $output, $exit); 
    return $exit == 0; 
} 

Crédits: Fonction a été adaptée à partir https://segment.com/blog/how-to-make-async-requests-in-php/