[Pregunta]: Usuario conectado (Señal verde) Un poco de logica...

Iniciado por Leguim, 10 Octubre 2019, 02:11 AM

0 Miembros y 1 Visitante están viendo este tema.

Leguim

Buenas noches,
Quería hacer un sistema (ya conocido) donde se muestre con x icono o estado a un usuario que está conectado (sesión iniciada)

Yo haría así: crear un campo en la tabla usuarios que se llame campo de (tipo tyni int) de manera que solo guarde 0 y 1... el 0 desconectado y 1 conectado... cuando inicie sesión el usuario su campo conectado será = 1 y cuando cierre sesión (logout) será = 0

Me parece que esta logica se queda corta... que opinan???

#!drvy

Generalmente se suele usar un sistema de acción directa (el usuario se puede conectar o desconectar manualmente) + un timeout desde su última acción. Imaginate que un usuario se conecta pero nunca se "desconecta".. ese caso se resuelve mediante un sistema que guarda un timestamp (por ejemplo) de su última acción y si digamos han pasado más de 15 minutos desde entonces, se le marca como desconectado.

Lo puedes ver en este mismo foro abajo del todo donde pone "Usuarios en linea".

Saludos

Leguim

Hola!

Imagino que para esto deba de usar ajax para el timeout y luego ejecutar codigo php donde cierro la sesion y lo marco como desconectado, aunque imaginate que la persona no cierra su sesión y solamente cierra la pestaña de google dicha sesión queda abierta pero el navegador o el cliente ya fue cerrado... entonces como ejecutaria esto?

#!drvy

#3
Creo que no lo has entendido. Vamos plantear un sistema con pseudocódigo.

Planteamiento de la tabla:

user_id | name | password | online | last_active.

user y password guardarian lo que tu imaginas que guardan. online puede guardar un estado forzado de 0 o 1 según el usuario. last_active guardaría un timestamp de la ultima acción que ha realizado el usuario.

Ejemplo
1 | drvy | abcd123456abcd | 1 | 1571126689

Soy drvy, con id 1, tengo un hash muy raro, estoy conectado y mi última acción fue a las 10/15/2019 @ 8:04am (UTC).


Bien, ahora, cada vez que navegue a una página, o haga una acción cualquiera mientras este identificado como drvy, vas a actualizar el campo last_active por el timestamp actual.

Primer user case:
- Inicio sesión ->el sistema guarda timestamp y pone la columna "online" en 1.
--- Navegó a mi perfil -> el sistema guarda timestamp
------ Me cambio el correo -> el sistema guarda timestamp
--- Voy a la portada -> el sistema guarda timestamp
- Cierro la sesión -> el sistema guarda timestamp y pone la columna "online" en 0.

Segundo user case:
- Inicio sesión -> el sistema guarda timestamp y pone la columna "online" en 1.
--- Navegó a mi perfil -> el sistema guarda timestamp
------ Me cambio el correo -> el sistema guarda timestamp
--- Voy a la portada -> el sistema guarda timestamp
- Cierro la pestaña sin cerrar sesión.


Ahora, la función para comprobar si el usuario esta online:

bool isOnline (int user_id) {
   int grace_period = (time() - 1200);
   char query = 'SELECT user_id FROM users WHERE user_id = ' . user_id . ' AND (online = 1 AND last_active > ' . grace_period . ')';
   return (make_query(query) > 0 ? true : false);
}


Que hacemos. Establecemos un periodo de gracia de 20 minutos (1200 segundos que se restan al tiempo actual). Hacemos una query que dice: Dame todos los usuarios cuyo id es user_id y que: están marcados como que estan online y su ultima acción fue dentro del periodo de gracia y si la query retorna algún usuario (más de 0) es que el user_id está online. Así, si un usuario se sale sin cerrar la sesión, solo se le verá como online durante 20 minutos más o si sale de manera adecuada se le mostrará como offline de inmediato.

En el primer user case, desde que inicia sesión hasta que la cierra se le verá online e inmediatamente después se le verá como offline. En el segundo user case, se le verá online desde que inicia sesión hasta pasados 20 minutos de el cerrar la pestaña (y por lo tanto no realizar ninguna acción).

De hecho el sistema de este foro ni siquiera utiliza la columna online. Simplemente se basa en la cuando fue la última acción de usuario para considerarlo en linea o no.


Saludos

Leguim

Woao, nada que ver lo que pensaba de como hacerlo... Está muy buena tu idea!
aunque todavía tengo una pregunta (algo tonta) pero ¿Donde podría ejecutar la función de php is_online(id_user); ?

Gracias!!!

WHK

Puedes utilizar websocket sin la necesidad de utilizar bases de datos, asi puedes saber cuando un usuario está en línea o no, enganchas cada item de usuario a un id de evento distinto y lanzas una conexión de un solo websocket y ya.

Saludos.

Leguim

#6
WHK: realmente estuve pensando en usar sockets en mi aplicación web pero no solamente me parece algo difícil (pero difícil en serio, a cada rato trato de entenderlo mirando vídeos o buscando información, pero no lo entiendo), que necesitas abrir una consola, que después no entiendo como puedo ejecutar los sockets ya cuando la aplicación esté en producción... si usar sockets de alguna manera tiene vulnerabilidades y hay que parchearlas, (no estoy seguro de esta ultima)

!#drvy: ¿Donde podría ejecutar la función de php is_online(id_user); ?  :silbar:

Leguim

#7
Estaba pensando poner la función "Is_Online" es decir, que se ejecute cada 10 minutos pero de una forma más global, es decir:

Código (php) [Seleccionar]

function Is_Online($id_user)
{
    [Edita en la base de datos donde la id de usuario sea igual a id_user y conectado = 1 y el tiempo de gracia excedió]
}

// y cambiar por
function Is_Online()
{
      [Editar en la base de datos todos los usuarios donde conectado = 1 y el tiempo de gracia se excedió]
}


Pero no se como puedo hacer que cada 10m o 1m se pueda ejecutar esta consulta y si es recomendable.

Hacer algo como "LongPolling" pero nose por donde empezar, si me pudieran decir si esto es recomendable se los agradezco mucho.