2010-02-03 128 views
20

Estoy escribiendo un servicio REST simple, que responde a las solicitudes de los clientes. Todo en PHP.¿Enviando solicitudes de POST sin esperar respuesta?

Mi preocupación es que cuando mi servidor responda a una solicitud, podría terminar bloqueando recursos si el lado del cliente es demasiado lento para devolver la respuesta "ok".

¿Cómo envío una solicitud POST a través de lib_curl configurándola para que no espere ninguna respuesta, sino que salga inmediatamente después de que se hayan enviado los datos POST?

¿Esto es posible? Gracias !

+1

No es el cliente el que envía la respuesta 200 OK, sino el servidor. El cliente realiza una solicitud y el servidor responde, al servidor no le importa lo que está pasando con el cliente (por definición en REST, es sin estado). ¿Qué estás tratando de hacer? ¿Podrías dar más detalles? – meouw

Respuesta

13

No se puede enviar datos sin recibir una respuesta con HTTP. HTTP siempre va solicitud -> respuesta. Incluso si la respuesta es muy corta (como un simple 200 sin texto), debe haber una respuesta. Y cada socket HTTP esperará esa respuesta.

Si no le importa la respuesta, puede agregar un proceso al servidor que realiza sus solicitudes, y solo presione sus datos de solicitud (como un servicio que se ejecuta en segundo plano, verificando una base de datos de solicitudes, y siempre comenzando la solicitud cada vez que se agrega una nueva entrada). De esta forma, realizaría la solicitud de forma asíncrona y podría finalizar tan pronto como agregue esa solicitud al paquete .

También como dijo anteriormente, el cliente no forma parte de ninguna comunicación que esté haciendo con php. Php es un lenguaje del lado del servidor, así que cuando el cliente solicita una página web (el archivo php), el servidor ejecuta ese archivo (y hace todas las solicitudes que el archivo php declara) y luego devuelve el resultado al cliente.

+0

Eso es lo que necesitaba saber :) Gracias – Gotys

+0

@Gotys sidenote, si solo desea enviar una "solicitud" sin esperar una respuesta, busque en el protocolo UDP – chris

+0

Existe el fuego y olvide el "patrón". Una solicitud asyc activará la solicitud. Una vez ejecutado, puede hacer otra cosa sin esperar. En el escenario donde tiene una conexión de red confiable, UDP es una opción, pero TCP es más confiable ya que sabe que los paquetes lo harán. Sin embargo, sin verificar la respuesta, no sabrá qué sucedió. –

1

Nunca lo he intentado, pero establecer el CURLOPT_TIMEOUT a un valor muy bajo podría hacer el truco. Pruebe 0 o 0.1.

Sin embargo, no sé cómo se comportarán cURL y el cliente con esto, si la conexión se cancelará activamente cuando la conexión ya esté establecida y si se alcanza el tiempo de espera. Deberías probar Si llama a scripts PHP, tal vez ignore_user_abort() puede asegurarse de que sus scripts se ejecuten de cualquier manera.

+2

curl 0 timeout lo dejaría funcionar más tiempo – Boy

+0

Si va a intentar un tiempo de espera bajo, use la variación en milisegundos curl_setopt ($ curl, CURLOPT_TIMEOUT_MS, 1); –

12

aquí:

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

y el rizo:

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

Podría dar una explicación de por qué esto funciona –

+1

Encontré varias soluciones que incluían la parte del búfer de salida, pero todavía no funcionaba para mí hasta que agregué esas opciones de curvatura. ¡Gracias! –

3

Si realmente no se preocupan por la respuesta que está probablemente mejor fuera de exec -ing un comando wget. Esto se menciona de pasada en algunas de las otras respuestas, pero aquí es una función muy fácil para el envío de un paquete _POST a través de este enfoque (que es asíncrona y toma 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éditos: Función fue adaptado de https://segment.com/blog/how-to-make-async-requests-in-php/

Cuestiones relacionadas