Foros del Web » Programando para Internet » Node.js »

[SOLUCIONADO] Callback node.js

Estas en el tema de Callback node.js en el foro de Node.js en Foros del Web. Hola!, tengo un problema bastante avanzado..., espero me puedan ayudar, se los planteo: Estoy haciendo un chat para usuarios que tengo en una base de ...
  #1 (permalink)  
Antiguo 11/01/2014, 18:23
 
Fecha de Ingreso: febrero-2009
Mensajes: 151
Antigüedad: 15 años, 2 meses
Puntos: 1
Callback node.js

Hola!, tengo un problema bastante avanzado..., espero me puedan ayudar, se los planteo:

Estoy haciendo un chat para usuarios que tengo en una base de datos, el desafio:

Hacer que cuando el mismo usuarios se conecte desde otra hubicacion cierre la sesion que tenia abierta e incie la nueva

Lo que tengo es:

Cuando un usuario se conecta:

Código HTML:
for (i in usuariosConectados)
                {
                   if(usuariosConectados[i].id == rows[0].id) {
                      //le envio un mensaje a la hubicacion anterior informandoleio.sockets.socket(usuariosConectados[i].socket).emit("alerta_desconectar");
                   }
                }

                //Lo agrego al objeto
                usuariosConectados[rows[0].id]={
                                        'id':rows[0].id,
                                        'nombre': rows[0].display_name,
                                        'socket': socket.id,                                            
                                        };
Como se puede ver primero reviso si el usuario estaba conectado, en caso de estar conectado, llamo a la funcion alerta_desconectar como se muestra arriba, esta funcion del lado del cliente es:

Código HTML:
function alerta_desconectar(){
                alert("Se ha cerrado la sesion porque ha iniciado sesion  desde otra ubicacion, pestaña o ventana");
                socket.emit('desconectar');
             }
y desde esta funcion se llama a la funcion desconectar en el servidor que es:

Código HTML:
socket.on('desconectar', function()
    {
      socket.disconnect()
    });
Y luego continuo agregando el usuario al objeto usuariosConectados.

Parece que todo va bien pero al forzar la desconeccion se dispara automaticamente la funcion socket.on('disconnect') que tengo tambien definida y que lo que hace es, quitar al usuario de la lista de conectados y borrarlo del objeto usuariosConectados. La consecuencia:

Al ingresar el cliente desde otra hubicacion:
a) lo desconecta de la hubicacion anterior
b) borra al usuario actual del objeto usuariosConectados provocando que todo ande mal

Se me ocurrio solucionarlo con callbacks para que no agrege la nueva conexion al objeto usuariosConectados hasta que haya terminado con todo ese proceso pero nose como deberia hacerlo ni si es la mejor opcion o la mas correcta, espero alguien pueda ayudarme ya que este problema excede mis conocimientos. Muchisimas gracias!!!
  #2 (permalink)  
Antiguo 11/01/2014, 23:56
Avatar de utan  
Fecha de Ingreso: agosto-2012
Mensajes: 126
Antigüedad: 11 años, 8 meses
Puntos: 17
Respuesta: Callback node.js

Hola,

Ya que usuariosConectados[i].id == rows[0].id son iguales , solo abrio otra ventana o se logeo con otro browser, lo que deves hacer es actulizar tu objeto con el nuevo socket.io..

Prueba creando una variable salvas el viejo socket.id como el id de la base de datos es el mismo entonces actualizas tu objeto , rows[0].display_name y socket.id después mandas el emit a usuario al que le pertenece el viejo id el de la variable , sin necesidad de borrarlo de usuariosConectados..

Ya que como todo es asyncronico cuando mandas el disconnect a la ventana antigua , la ventana nueva es salvada en tu usuariosConectados borrandolo y quizás mandando el disconnect también a la nueva ventana.
__________________
Mis conocimientos son limitado, pero si te puedo ayudar lo are gustoso mi chat particular, visitalo gracias http://rendezvouschat.com
  #3 (permalink)  
Antiguo 12/01/2014, 16:21
 
Fecha de Ingreso: febrero-2009
Mensajes: 151
Antigüedad: 15 años, 2 meses
Puntos: 1
Respuesta: Callback node.js

Cita:
Iniciado por utan Ver Mensaje
Hola,

Ya que usuariosConectados[i].id == rows[0].id son iguales , solo abrio otra ventana o se logeo con otro browser, lo que deves hacer es actulizar tu objeto con el nuevo socket.io..

Prueba creando una variable salvas el viejo socket.id como el id de la base de datos es el mismo entonces actualizas tu objeto , rows[0].display_name y socket.id después mandas el emit a usuario al que le pertenece el viejo id el de la variable , sin necesidad de borrarlo de usuariosConectados..

Ya que como todo es asyncronico cuando mandas el disconnect a la ventana antigua , la ventana nueva es salvada en tu usuariosConectados borrandolo y quizás mandando el disconnect también a la nueva ventana.
Hola utan!, muchas gracias por tu colaboracion, entiendo perfectamente lo que decis y tenes toda la razon en el razonamiento... el tema es que cuando lo desconecto al usuario viejo se dispara automaticamente esto (que lo tengo para cuando el usuario cierra el navegador):

Código HTML:
socket.on('disconnect', function () 
		{
			//Eliminamos al usuario del objeto
			delete usuariosConectados[socket.identificador];			
			//Mandamos la información a las Sockets para que se borre de la lista
			socket.broadcast.emit("usuarioDesconectado",socket.identificador);
		});
En socket.identificador es:

Código HTML:
socket.identificador=rows[0].id;
Por eso se me habia ocurrido usar callbacks para que luego de que haya hecho todo el proceso de desconexion recien se actualice o se agrege al objeto, pero no se como hacerlo . Espero pueden ayudarme porque esta muy complicado...
  #4 (permalink)  
Antiguo 12/01/2014, 18:09
Avatar de utan  
Fecha de Ingreso: agosto-2012
Mensajes: 126
Antigüedad: 11 años, 8 meses
Puntos: 17
Respuesta: Callback node.js

hola,
Ok, mira te borra el disconnect el usuario porque estas usando el mismo id de la base de datos..

La nueva ventana y el socket anterior utilizan el mismo id de la base de datos, por lo tanto cuando el nuevo entra el otro emite un disconnect y como el id es el mismo de la bd borra el que acaba de entrar..

Lo que tienes que hacer es re trabajar en tu lógica ya que no la puedes trabajar así...

Una idea seria que crearas otra row en tu base de datos y que esta tuviera un timestamp del nuevo login, el mismo id del usuario lo tendrías y no molestaría tu código mucho..

y podrías comprobar algo así.

Código Javascript:
Ver original
  1. socket.on('disconnect', function ()
  2.         {
  3.             //usas en vez del id del db, la timestamp de su reciente login
  4.             delete usuariosConectados[socket.timestamp];           
  5.             //Mandamos la información a las Sockets para que se borre de la lista
  6.             socket.broadcast.emit("usuarioDesconectado",socket.identificador);
  7.         });

Usas en vez del id del db, la timestamp de su antiguo login el cual es el mismo id de la db del usuario pero la timestamp lo define como diferente .. así no borrara al mas reviente en tu objeto..
Este es un ejemplo mas claro de mi idea , puede haver bugs:

Código Javascript:
Ver original
  1. var clients = {};
  2.    
  3.     server.on( 'connection' , function( socket ){
  4.         // obtenemos de la BD
  5.         //db.id , db.screen_name,db.timestamp
  6.         for ( i in clients ){
  7.             // si no existe crear nuevo
  8.             if( clients[i] && clients[i].id !== db.id ){
  9.                 socket.identifier   =   db.timestamp;
  10.                
  11.                 clients[db.timestamp] = {
  12.                     id          : db.id,
  13.                     screen_name   : db.screen_name,
  14.                     sockId      : socket.id,
  15.                      timestamp  :db.timestamp
  16.                 }
  17.             }else{
  18.             // inicializa el disconnect de el socket antiguo
  19.             var old_socket  =   socket.sockets.sockets[clients[i].sockId];
  20.                 old_socket.json.emit('user_lef' , 'user left the app');
  21.                 old_socket.disconnect();
  22.             }          
  23.            
  24.         }
  25.        
  26.        
  27.         server.on('disconnect' , function(){
  28.             if( clients[socket.timestamp] ) delete clients[socket.timestamp];
  29.         });
  30.     });
__________________
Mis conocimientos son limitado, pero si te puedo ayudar lo are gustoso mi chat particular, visitalo gracias http://rendezvouschat.com

Última edición por utan; 13/01/2014 a las 09:03
  #5 (permalink)  
Antiguo 13/01/2014, 12:04
 
Fecha de Ingreso: febrero-2009
Mensajes: 151
Antigüedad: 15 años, 2 meses
Puntos: 1
Respuesta: Callback node.js

Cita:
Iniciado por utan Ver Mensaje
hola,
Ok, mira te borra el disconnect el usuario porque estas usando el mismo id de la base de datos..

La nueva ventana y el socket anterior utilizan el mismo id de la base de datos, por lo tanto cuando el nuevo entra el otro emite un disconnect y como el id es el mismo de la bd borra el que acaba de entrar..

Lo que tienes que hacer es re trabajar en tu lógica ya que no la puedes trabajar así...

Una idea seria que crearas otra row en tu base de datos y que esta tuviera un timestamp del nuevo login, el mismo id del usuario lo tendrías y no molestaría tu código mucho..

y podrías comprobar algo así.

Código Javascript:
Ver original
  1. socket.on('disconnect', function ()
  2.         {
  3.             //usas en vez del id del db, la timestamp de su reciente login
  4.             delete usuariosConectados[socket.timestamp];           
  5.             //Mandamos la información a las Sockets para que se borre de la lista
  6.             socket.broadcast.emit("usuarioDesconectado",socket.identificador);
  7.         });

Usas en vez del id del db, la timestamp de su antiguo login el cual es el mismo id de la db del usuario pero la timestamp lo define como diferente .. así no borrara al mas reviente en tu objeto..
Este es un ejemplo mas claro de mi idea , puede haver bugs:

Código Javascript:
Ver original
  1. var clients = {};
  2.    
  3.     server.on( 'connection' , function( socket ){
  4.         // obtenemos de la BD
  5.         //db.id , db.screen_name,db.timestamp
  6.         for ( i in clients ){
  7.             // si no existe crear nuevo
  8.             if( clients[i] && clients[i].id !== db.id ){
  9.                 socket.identifier   =   db.timestamp;
  10.                
  11.                 clients[db.timestamp] = {
  12.                     id          : db.id,
  13.                     screen_name   : db.screen_name,
  14.                     sockId      : socket.id,
  15.                      timestamp  :db.timestamp
  16.                 }
  17.             }else{
  18.             // inicializa el disconnect de el socket antiguo
  19.             var old_socket  =   socket.sockets.sockets[clients[i].sockId];
  20.                 old_socket.json.emit('user_lef' , 'user left the app');
  21.                 old_socket.disconnect();
  22.             }          
  23.            
  24.         }
  25.        
  26.        
  27.         server.on('disconnect' , function(){
  28.             if( clients[socket.timestamp] ) delete clients[socket.timestamp];
  29.         });
  30.     });
Muy biena idea!, lo voy a intentar y te cuento como me va. Gracias!
  #6 (permalink)  
Antiguo 13/01/2014, 14:40
 
Fecha de Ingreso: febrero-2009
Mensajes: 151
Antigüedad: 15 años, 2 meses
Puntos: 1
Respuesta: Callback node.js

Muchisimas gracias Utan, ya lo solucione!, solo usando el timestamp, no lo habria logrado sin tu ayuda!. Gracias de nuevo!!!

Etiquetas: callback
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:03.