2011-12-11 2 views
8

riesco solo i messaggi emettere agli utenti quando la loro presa di id è stato memorizzato direttamente all'interno del io.sockets.on ('connect') la funzione. Non so il motivo per cui non funziona quando si cerca di conservare la loro presa id dopo che sono loggatoInvio di un messaggio a un client tramite il suo socket.id

di lavoro:.

Non funziona:

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"); 
     } 
    } 
    } 

Snippet di codice lato client JavaScript

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

Soluzione: Grazie @alessioalex ho dovuto eliminare il riferimento alla socket.io dalla pagina di login, e aggiungere il seguente in io.sockets.on ('connessione')

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 
}) 

risposta

25

Ci sono alcuni problemi con il tuo codice, il primo è che non devi autenticare gli utenti tramite Socket.IO, dovresti assicurarti che possano connettersi solo dopo essersi autenticati. Se si utilizza espresso, quindi il seguente articolo può aiutare molto: http://www.danielbaulig.de/socket-ioexpress/

Inoltre si dovrebbe essere evitando l'invio di messaggi in questo modo, dal momento che è parte della Socket.IO internamente e possono cambiare:

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

invece (se si desidera inviare un messaggio a un client specifico) è meglio tenere un oggetto ad esempio con i client connessi (e rimuovere il cliente una volta disconnesso):

// 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"); 
} 

Certo, io.sockets.socket(id) può funzionare (didn ' in realtà test), ma può anche essere sempre modificato poiché fa parte degli interni di Socket.IO, quindi la mia soluzione sopra è più "sicura".

Un'altra cosa che si potrebbe voler modificare nel codice sul lato client è var socket = io.connect(''); con var socket = io.connect('http://localhost');, come si può vedere nell'esempio ufficiale della Socket.IO qui: http://socket.io/#how-to-use

+0

Grazie, funziona tuttavia quando provo ad usare socket.on ('login', .....) {utenti [u] = socket.id} non funziona. Posso solo aggiungere utenti direttamente all'interno di io.sockets.on ('connessione') – Jack

+1

Sei sicuro? Poiché socket è una variabile definita "above", dovrebbe essere visibile anche in quella funzione, proprio come nel mio esempio con disconnect. – alessioalex

+1

Ho modificato la domanda per mostrarti un esempio funzionante e non funzionante. Non riesco a capire perché non mi consenta di inviare messaggi nell'esempio "non funzionante" sopra riportato. – Jack

2

vedo che questo post sta generando un bel po 'di interesse ... quindi ho intenzione di pubblicare il codice che ho usato per implementare questo:

Note

ho usato Redis come mezzo di immagazzinamento sessione. La sessione viene inizialmente configurata durante la pagina di accesso tramite una richiesta HTTP contenente i dettagli degli utenti, se questi dettagli sono validi (confrontati con un documento MongoDB) ... quindi viene creata la sessione.

codice lato server Creazione e rimozione di sessione/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 
    }) 
.... 
} 

Server Side Messaggio selettiva Invio

Questo codice mi permette di inviare un messaggio ai membri del team di progetto. Un team di utenti non riceverà messaggi da un team separato di utenti.

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"); 
    } 
    } 
}