Me gustaría actualizar mi página web estática que se ejecuta en apache cuando cambia el índice. Ya intenté usar eventos del lado del servidor, donde tenía un archivo PHP que verificaba si el índice cambiaba y, en caso afirmativo, enviaba el evento a la página web. Esto funciona exactamente como quiero, pero hay un problema. Debido a que la página es utilizada por muchas personas a veces (decenas o hasta cien pestañas abiertas), rápidamente comienza a enviar spam a muchos procesos de apache. Luego, llega al límite y el apache se congela. La pregunta es cómo manejar esto. Si un usuario cierra la pestaña, el proceso se cancela; sin embargo, si no, apache se congela.
El script PHP se ve así (está verificando dos cosas, primero, si el archivo cambió, o segundo, si el estado es algo. Como dije, esto funciona bien, el problema es que está retrasando el servidor):
<?php session_start(); session_write_close(); ignore_user_abort(false); header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $filename = "index.html"; while(True){ if ( connection_aborted() ){ exit(); }else{ try{ $string = file_get_contents("current_status.json"); $json = json_decode($string, true); $pom1 = $json["state"]; $t1 = shell_exec("date -r index.html"); sleep(3); $pom2 = $json["state"]; if($t1 != shell_exec("date -r index.html")) { sleep(2); echo "data: file changed \n\n"; } else if($pom2=="ready") { sleep(2); echo "data: new shot available \n\n"; } else { echo "heartbeat"; } ob_flush(); flush(); } catch (\Error $e){ echo "data: error, json not available \n\n"; } } } ob_end_flush() ?>
Luego, hay una función javascript clásica en el archivo de índice con fuente de eventos en el archivo PHP.
Mi pregunta es, ¿cómo puedo hacer esto para que Apache no se bloquee? ¿Puedo configurar SSE de alguna manera para manejarlo? Sé que puedo permitir más procesos en apache, pero mis recursos son limitados.
¿Hay alguna otra manera de cómo hacer esto? Por ejemplo, live.js también funciona, pero el problema es el mismo, muchos procesos cuando se abren varias veces.
Sí, puedo ver cómo esto ejercería mucha más presión en su servidor de lo necesario.
Lo que debe hacer es sondear los cambios de javascript. Envía una solicitud asíncrona por última vez que el archivo de índice cambió desde su javascript. Lo haces una vez cuando se carga la página y almacenas la hora. Luego verifica nuevamente en un intervalo y compara el resultado con el primero. Si cambió, actualice la página. El script PHP debe obtener la última fecha de cambio, mostrarlo y salir; no hay scripts PHP que se ejecuten continuamente.
Así es como debería verse el archivo PHP:
<?php header('Content-type: text/plain'); echo filemtime('index.html'); ?>
Mantén esto mínimo. La función filemtime incorporada es más eficiente que ejecutar comandos shell_exec.
Aquí hay un javascript de ejemplo:
chk_index_change_time(false); function chk_index_change_time(last){ fetch('http://yourdomain.com/yourpath/get_index_change_time.php') .then(res => res.text()) .then((index_change_time) => { if ((false !== last) && (last != index_change_time)){ location.reload(); } else { setTimeout(chk_index_change_time, 3000, index_change_time); } }); }
Siéntase libre de manejar errores o lo que sea, pero esto funcionará. Usé un tiempo de espera aquí en lugar de un intervalo para que si el servidor es lento, el tiempo de respuesta del servidor no salga del retraso de 3 segundos.