¿Puedo detectar cuando un cliente se ha desconectado de un CGI?

¿Puedo detectar cuando un cliente se ha desconectado de un CGI?

Tengo un CGI que requiere bastantes recursos y que tarda bastante en comenzar a enviar datos. Hemos visto bastantes casos en los que personas impacientes recargan un par de veces, lo que luego provoca que se carguen ejecuciones adicionales del CGI, o casos en los que el cliente agota el tiempo de espera y desconecta la conexión, pero el CGI sigue ejecutándose.

¿Existe alguna buena forma de detectar cuándo ha sucedido esto? Ni siquiera es necesario que esté dentro del propio CGI (y probablemente sea mejor si no lo está, se lo pasa a otro programa sobre el que no tengo control), pero podría ser un trabajo cron que se ejecuta de vez en cuando. buscar conexiones muertas para cosechar.

Actualmente estoy usando Apache, pero este es un problema tal que estaría dispuesto a ejecutar algún otro servidor web si tiene disposiciones para solucionarlo (o una forma de permitirme monitorear el problema).

Respuesta1

Por lo general, no puede detectar una conexión interrumpida hasta que comience a escribirle al usuario. De lo contrario, su proceso continuará haciendo su trabajo sin notar la interrupción de la conexión por parte del usuario.Esta publicaciónestá relacionado incluso si habla de PHP. El concepto debería ser el mismo.

Hay cosas posibles que puedes probar:

  1. Realice el trabajo que requiere mucho tiempo en segundo plano. Cuando un usuario solicita el CGI, no ejecute la tarea como una llamada de bloqueo normal. Simplemente devuelva cualquier cosa al usuario para indicarle que la solicitud se está procesando. Por supuesto, debe encontrar alguna forma de actualizar la vista o proporcionar otra página para verificar el estado del trabajo utilizando alguna ID de solicitud o IP.
  2. Envíe los datos al cliente lo antes posible y salga si no se pudo enviar (indicación de conexión interrumpida). Por ejemplo, puede enviar el progreso del trabajo cada pocos segundos o minutos.

Si guarda los trabajos que se están ejecutando actualmente en una base de datos, puede guardar el ID de solicitud y/o la dirección IP del cliente. Por lo tanto, puede detectar e ignorar solicitudes duplicadas al mismo recurso diciéndole al usuario "su solicitud está en procesamiento".

Respuesta2

Advertencia: esta información puede estar obsoleta. Ver último párrafo.

Recuerdo haber tenido el mismo problema y solucionarlo con unnph(sin encabezado de análisis) Script CGI.

Normalmente, Apache recopila todos los encabezados de su script y, cuando termina de leerlos, los modifica con algunos encabezados estándar que usted no proporcionó. Lo que también significa que, mientras no termine los encabezados, Apache no envía nada al cliente.

Con un script nph, deberá proporcionar todos los encabezados, pero Apache los enviará al cliente inmediatamente y enviará un SIGPIPE a su script CGI una vez que el cliente se desconecte. Por lo tanto, puede enviar un X-Slowly-Counting-Part-nnn: yesencabezado cada pocos segundos para evitar tiempos de espera en el cliente y recibirá una notificación si el cliente interrumpe la conexión.

Esto aún deja el problema: tendrás que enviar el estado HTTP primero, pero si envías un 'Content-Length: 0', o tal vez un 'Content-Length: 1' y cierras la conexión sin enviar ningún contenido, tu archivo descargadordeberíaasumir un error de red y actuar en consecuencia.

Probablemente tendrá que canalizar la salida del otro programa a través de su proceso, pero esto no debería ser un gran impacto en el rendimiento al menos si está en Linux y usa la sendfile(2)llamada al sistema.

El problema con todo esto es que lo usé hace al menos 10 años, probablemente en Apache 1.3, y buscar en Google apache cgi nphno arrojó nada útil. Entonces, tal vez la función nph se eliminó mientras tanto, pero quizás no, admito que no busqué mucho.

Respuesta3

Antigua pregunta, pero tuve el mismo problema y lo solucioné comprobando si la conexión está establecida:

En mi caso, estoy ejecutando un script bash en el servidor... las variables env son exportadas por mod_cgi. Creo que esta solución funcionará para cualquier programa/script que se ejecute en CGI.

ss -nt state established "( sport = :$SERVER_PORT and dport = $REMOTE_ADDR:$REMOTE_PORT )" 2>/dev/null | grep -q "$REMOTE_ADDR:$REMOTE_PORT"
if [ "$?" -ne '0' ]; then
     # Client closed browser/connection
fi

información relacionada