¿Cuál es la forma más fácil de determinar si un usuario está en línea? (PHP / MYSQL)

StackOverflow https://stackoverflow.com/questions/1051895

  •  20-08-2019
  •  | 
  •  

Pregunta

¿Hay alguna forma en que pueda aprovechar las sesiones para saber si el usuario está en línea?

Es decir: uso de registros, configuro una variable $ _SESSION, el usuario agota el tiempo de espera El recolector de basura de la cookie actualiza la base de datos para actualizar su estado como fuera de línea.

EDIT: Quiero una solución que no implique horas o fechas. Quiero algo para montar en sesiones o algo similar. Adivinar si alguien está en línea no es lo suficientemente bueno para lo que necesito.

¿Fue útil?

Solución

No te molestes en descubrir las diferencias entre las zonas horarias. Eso no es necesario.

Siempre que el usuario acceda a una página, actualice un campo en su registro de la tabla Usuarios última vez actualizado. Luego haga una consulta para todos los usuarios que tengan un tiempo de última actualización en los últimos 5 minutos. Algo más que esto, y se consideran & Quot; offline. & Quot;

Si usa su hora de servidor, a través de la función NOW () en MySQL, evitará el cálculo de diferencias entre zonas horarias.

Esta es la forma estándar de rastrear cuántos usuarios están actualmente en línea (es decir, activos en los últimos minutos).

Constantemente actualizado

Si desea saber que todavía están activos, incluso cuando no están saltando de una página a otra, incluya un poco de javascript para hacer ping a su servidor cada 60 segundos más o menos para hacerle saber que todavía están vivos. Funcionará de la misma manera que mi sugerencia original, pero actualizará sus registros sin requerir que naveguen frenéticamente en su sitio al menos una vez cada cinco minutos.

var stillAlive = setInterval(function () {
    /* XHR back to server
       Example uses jQuery */
    $.get("stillAlive.php");
}, 60000);

Otros consejos

Lo que está pidiendo (después de la aclaración) es, por definición, imposible. HTTP es un protocolo sin conexión, por lo que tan pronto como un usuario llega a una página y todo el contenido regresa del servidor al navegador del usuario, no hay conexión entre los dos. Alguien está & Quot; en línea & Quot; con su sitio web por menos de un segundo.

Una cosa que podría hacer es tener JavaScript en su página web para hacer solicitudes AJAX a su servidor de forma regular que incluye información de identificación y una solicitud AJAX diferente cuando el usuario abandona la página , usando window.onbeforeunload .

Puede que mi camino no sea el mejor, pero dado que mi sitio y mi base de usuarios están en mysql DB, cuando un usuario inicia sesión en mi sitio,

  1. Actualizo la tabla de usuario para decir que están en línea
  2. Insértelos en una tabla en línea
  3. Luego configuré una sesión con el hora actual

Luego, en cada carga de la página, verifico la sesión de tiempo en línea, si existe, verifico para ver qué edad tiene, si tiene menos de 5 minutos de antigüedad, no hago nada, si es más antigua de 5 minutos, luego actualizo la hora de la sesión nuevamente con la hora actual y también actualizo la tabla de usuarios en línea con la hora

Luego tengo un trabajo cron que se ejecuta cada 10-15 minutos que elimina cualquier uso de la tabla en línea y marca la tabla de usuario como fuera de línea si el tiempo en línea se ha actualizado en X cantidad de minutos

Parece que su " es la persona en línea " La lógica de comparación no tiene en cuenta las zonas horarias. Si está tratando con zonas horarias de esta manera, le recomiendo que almacene todos sus tiempos en GMT y los convierta a la hora local para sus usuarios justo antes de mostrarlos. Esto hará que cualquier operación de comparación sea muy simple.

Hay un buen hilo SO sobre las zonas horarias aquí .

Una cosa que recomendaría es almacenar este tipo de información en la memoria con, por ejemplo, memcached o mysql heap o redis. Porque de lo contrario, la base de datos se verá afectada mucho.

Almacene la zona horaria en la tabla y úsela en un cálculo para encontrar la hora local de los usuarios en comparación con la hora local del usuario que ve la página.

Edición :

Mejor aún, almacene todos los tiempos como la hora del servidor y base todos los cálculos relativos solo a la hora del servidor.

Depende de su situación, puede ser mejor para usted crear una tabla separada " cuya línea " con las columnas: " ip " y " last-updated-time " y consulta / actualiza esta tabla cada vez que un usuario carga una página.

Las consultas de carga en la página pueden incluir :

  1. Actualizar / insertar " cuya-línea " tabla para el usuario actual basada en ip.
  2. Eliminar " expiró " filas (también se puede hacer periódicamente usando cronjob).
  3. Count " active " usuarios.

Beneficios de usar esta técnica :

  1. Si un usuario no ha iniciado sesión, él / ella todavía está siendo contado / rastreado.
  2. Depende de la cantidad de usuarios que tenga, consultar esta tabla puede ser más rápido.

Nota: Si usa esto, debe tener en cuenta que cualquier vista de página creará una fila en su tabla, por lo que según el agente de uso puede ignorar los bots o solo contar los populares (Firefox, IE, Safari, Opera, etc. ).

La solución que he implementado para esto es, en cada carga de la página por un usuario autenticado, establecer / restablecer una var memcache como " user_ {userid} isonline " = > cierto y caducar en 5 minutos. Luego verifique si la var está en el caché cuando accedo a la información del usuario. Dependiendo del tamaño de su base de usuarios, si desea obtener una lista de todos los que están en línea, puede usar una llamada memcache getmulti con una matriz de & Quot; user {userid} _isonline & Quot; claves para todos sus usuarios.

por supuesto, esto realmente depende de la frecuencia con la que un usuario cambiará las páginas de su sitio ... para obtener una representación más precisa de los usuarios en línea, puede implementar una llamada ajax xmlhttprequest en su página que se ejecuta en un pequeño intervalo ( 30 segundos más o menos) que restablece el memcache var y hace que el memcache var caduque en menos tiempo (1 minuto para tener en cuenta los posibles problemas del navegador). Esto no es COMPLETAMENTE exacto, pero como http no tiene una conexión persistente con el servidor, está bastante limitado en lo que puede hacer.

SI necesita una representación de hasta el segundo de quién está en línea, tal vez podría tener una aplicación flash cargada en su página que se conecta a un servidor jabber, luego simplemente verifique si ese usuario en particular ha iniciado sesión en el servidor.

También puede usar la etiqueta onunload ... en el cuerpo Más información aquí ( https://www.w3schools.com/jsref/event_onunload.asp)

De esta manera, no tiene que esperar de 4 a 5 minutos para que el usuario se desconecte.

Pero aún debe usar el método de actualización ajax en caso de que el navegador del usuario falle ...

Aquí hay una manera de cómo obtener la diferencia entre dos fechas de una base de datos en minutos, luego verifique la diferencia y establezca el estado en línea / fuera de línea.

$query = 'SELECT * FROM Users';
$result = mysqli_query($mysqli, $query);

foreach($result as $user){
    // date from the database
    $dbLastActivity = date("d-m-Y h:i:s a", strtotime($user['lastOnline']));
    // date now
    $now = date("d-m-Y h:i:s a", $date);

    // calculate the difference
    $difference = strtotime($now) - strtotime($dbLastActivity);
    $difference_in_minutes = $difference / 60;

    // check if difference is greater than five minutes
    if($difference_in_minutes < 5){
        // set online status
        $updateStatus = 'UPDATE Users SET Status="online" WHERE lastOnline="'.$user['lastOnline'].'"';
    } else {
        // set offline status
        $updateStatus = 'UPDATE Users SET Status="offline" WHERE lastOnline="'.$user['lastOnline'].'"';
    }

    // check if mysqli query was successful
    if (!$mysqli->query($updateStatus)){
        printf("Error Message %s\n", $mysqli->error);
    }
} 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top