2011-12-11 17 views
8

Parece que solo puedo emitir mensajes a los usuarios cuando su id. De socket se ha almacenado directamente en la función io.sockets.on ('connect'). No sé por qué no funciona cuando se trata de almacenar su ID toma después de que hayan iniciado sesión enEnviar un mensaje a un cliente a través de su socket.id

de Trabajo:.

No trabaja:

var clients = {}; 
    /** A new socket connection has been accepted */ 
    io.sockets.on('connection', function (socket) 
    { 
    //Used to access session id 
    var hs = socket.handshake;    
     clients[socket.id] = socket; // add the client data to the hash    

    socket.on('user-login', function(user){   
     if(!users['brownj2']){ 
     users['brownj2'] = socket.id; // connected user with its socket.id 
     } 
    }) 

    socket.on('page-load', function(pid) 
    { 
     if(users['brownj2']) 
     {   
     clients[users['brownj2']].emit('hello'); 
     } 
     else 
     { 
     console.log("NOT FOUND BROWNJ2"); 
     } 
    } 
    } 

JavaScript Fragmento de código del lado del cliente

var socket = io.connect(''); 
socket.on("hello", function(){ 
    alert("Hi Jack"); 
    console.log("WEBSOCKET RECIEVED"); 
}) 

Solución: Gracias @alessioalex he tenido que eliminar la referencia a Socket.IO desde la página de inicio de sesión, y añadir lo siguiente en io.sockets.on ('conexión')

var hs = socket.handshake; 

sessionStore.get(hs.sessionID, function(err, session){ 
    console.log("SESSION: " + util.inspect(session)); 

    clients[socket.id] = socket; // add the client data to the hash 
    validUsers[session.username] = socket.id; // connected user with its socket.id 
}) 

Respuesta

25

Hay algunos problemas con su código, el primero es que no debe autenticar a los usuarios a través de Socket.IO, debe asegurarse de que se puedan conectar solo después de autenticarse. Si está utilizando Express, a continuación, el siguiente artículo le puede ayudar mucho: http://www.danielbaulig.de/socket-ioexpress/

También usted debe ser evitar el envío de mensajes como tal, ya que es parte de Socket.IO internamente y pueden cambiar:

io.sockets.socket(id).emit('hello'); 

su lugar (si desea enviar un mensaje a un cliente específico) que es mejor mantener un objeto, por ejemplo, con los clientes conectados (y quitar el cliente una vez desconectado):

// the clients hash stores the sockets 
// the users hash stores the username of the connected user and its socket.id 
io.sockets.on('connection', function (socket) { 
    // get the handshake and the session object 
    var hs = socket.handshake; 
    users[hs.session.username] = socket.id; // connected user with its socket.id 
    clients[socket.id] = socket; // add the client data to the hash 
    ... 
    socket.on('disconnect', function() { 
    delete clients[socket.id]; // remove the client from the array 
    delete users[hs.session.username]; // remove connected user & socket.id 
    }); 
} 

// we want at some point to send a message to user 'alex' 
if (users['alex']) { 
    // we get the socket.id for the user alex 
    // and with that we can sent him a message using his socket (stored in clients) 
    clients[users['alex']].emit("Hello Alex, how've you been"); 
} 

Claro, io.sockets.socket(id) pueden trabajar (didn ' t en realidad prueba), pero también se puede cambiar siempre, ya que es parte del interior de Socket.IO, por lo que mi solución anterior es más 'segura'.

Otra cosa que puede que desee cambiar en el código del lado del cliente es var socket = io.connect(''); con var socket = io.connect('http://localhost');, como podemos ver en el ejemplo oficial de Socket.IO aquí: http://socket.io/#how-to-use

+0

Gracias, funciona sin embargo cuando intento utilizar socket.on ('login', .....) {usuarios [u] = socket.id} no funciona. Solo puedo agregar usuarios directamente dentro de io.sockets.on ('connection') – Jack

+1

¿Estás seguro? Como el socket es una variable definida 'arriba', también debería estar visible en esa función, tal como lo muestro en mi ejemplo con desconexión. – alessioalex

+1

He modificado la pregunta para mostrarle un ejemplo que funciona y no funciona. No puedo entender por qué no me permite enviar mensajes en el ejemplo 'no operativo' anterior. – Jack

2

puedo ver que está generando este post un buen montón de interés ... así que voy a publicar el código que utiliza para implementar esto:

Notas

he utilizado Redis como el almacenamiento de sesión. La sesión se configura inicialmente durante la página de inicio de sesión a través de una solicitud HTTP que contiene los detalles de los usuarios, si estos detalles son válidos (verificados en un documento MongoDB) ... entonces se crea la sesión.

Código del lado del servidor Creación y eliminación de Sesión/Socket

//Auth the user 
io.set('authorization', function (data, accept) { 
    // check if there's a cookie header 
    if (data.headers.cookie) { 
    data.cookie = parseCookie(data.headers.cookie); 
    data.sessionID = data.cookie['express.sid']; 

    //Save the session store to the data object 
    data.sessionStore = sessionStore; 

    sessionStore.get(data.sessionID, function(err, session){ 
     if(err) throw err; 

     if(!session) 
     { 
     console.error("Error whilst authorizing websocket handshake"); 
     accept('Error', false); 
     } 
     else 
     { 
     console.log("AUTH USERNAME: " + session.username); 
     if(session.username){ 
      data.session = new Session(data, session); 
      accept(null, true); 
     }else { 
      accept('Invalid User', false); 
     } 
     } 
    }) 
    } else { 
    console.error("No cookie was found whilst authorizing websocket handshake"); 
    return accept('No cookie transmitted.', false); 
    } 
}); 

/** A new socket connection has been accepted */ 
io.sockets.on('connection', function (socket) 
{  
    var hs = socket.handshake; 
    if(hs.session) 
    { 
    if(hs.session.username) 
    { 
     clients[socket.id] = socket; // add the client data to the hash 
     validUsers[hs.session.username] = socket.id; // connected user with its socket.id 
    } 
    } 


    socket.on('disconnect', function() 
    { 
    delete browsing[hs.session.username]; //Remove the client from the browsing hash 
    delete clients[socket.id];   // remove the client from the array 
    delete validUsers[hs.session.username]; // remove connected user & socket.id 
    }) 
.... 
} 

el lado del servidor de mensajes selectiva Envío

Este código permite que envíe un mensaje a los miembros del equipo de un proyecto. Un equipo de usuarios no recibirá mensajes de un equipo separado de usuarios.

for(var i = 0; i < project.team.length; i++) 
{ 
    if(validUsers[project.team[i].username]) 
    { 
    if(clients[validUsers[project.team[i].username]]) 
    { 
     projects.update({"_id" : projectId}, 
     {"$pull" : 
      {"stories" : {"_id" : storyId}} 
     } 
    );     
     clients[validUsers[project.team[i].username]].emit('delete-story', storyId); 
    } 
    else 
    { 
     console.error("Project team member not found"); 
    } 
    } 
} 
Cuestiones relacionadas