2011-12-11 17 views
8

Mogę tylko wydawać komunikaty emitowane użytkownikom, gdy ich identyfikator gniazda został bezpośrednio zapisany w funkcji io.sockets.on ("połącz"). Nie wiem, dlaczego to nie działa, gdy próbuje zapisać swój identyfikator gniazda po zalogowaniuWysyłanie wiadomości do klienta za pośrednictwem jej socket.id

działać.

Nie działa:

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

Kod strony po stronie klienta JavaScript

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

Rozwiązanie: Dzięki @alessioalex musiałem usunąć odwołanie do socket.io od strony logowania, a następnie dodaj następujące do io.sockets.on ('połączenie')

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

Odpowiedz

25

Występują pewne problemy z kodem, z których pierwszym nie należy uwierzytelniać użytkowników za pośrednictwem Socket.IO, należy się upewnić, że mogą się łączyć tylko po uwierzytelnieniu. Jeśli używasz Express, a następnie dodaje się artykuł może pomóc partii: http://www.danielbaulig.de/socket-ioexpress/

także powinno być unikanie wysyłania wiadomości jak tak, ponieważ jest to część Socket.IO wewnętrznie i mogą ulec zmianie:

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

Zamiast (jeśli chcesz wysłać wiadomość do konkretnego klienta), to lepiej zachować obiekt na przykład z podłączonych klientów (i usunąć klienta raz odłączony):

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

pewno io.sockets.socket(id) może działać (didn " t faktycznie test), ale także może być zawsze zmieniony, ponieważ jest częścią elementów wewnętrznych Socket.IO, więc moje powyższe rozwiązanie jest bardziej "bezpieczne".

Kolejną rzeczą może chcesz zmienić swój kod po stronie klienta jest var socket = io.connect(''); z var socket = io.connect('http://localhost');, jak możemy zobaczyć w oficjalnym przykład Socket.IO tutaj: http://socket.io/#how-to-use

+0

Dzięki, działa jednak gdy próbuję użyć socket.on ('login', .....) {użytkownicy [u] = socket.id} to nie działa. Mogę tylko dodawać użytkowników bezpośrednio do pliku io.sockets.on ('connection'). – Jack

+1

Jesteś pewien? Ponieważ gniazdo jest zmienną zdefiniowaną "powyżej", powinno być widoczne również w tej funkcji, tak jak pokazuję w moim przykładzie z rozłączeniem. – alessioalex

+1

Zmodowałem pytanie, aby pokazać Ci działający i niepracujący przykład. Nie wiem, dlaczego nie pozwoli mi wysyłać wiadomości w powyższym przykładzie "niepracującym". – Jack

2

widzę, że ten post jest generowanie sporo zainteresowania ... więc mam zamiar pisać kod użyłem do wdrożenia to:

Uwagi

użyłem Redis jako przechowywania sesji. Sesja jest początkowo konfigurowana na stronie logowania za pomocą żądania HTTP zawierającego dane użytkowników, jeśli te szczegóły są poprawne (Sprawdzono w dokumencie MongoDB) ... to sesja jest tworzona.

Server Side Code Tworzenie i usuwanie sesji/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 Selektywne Wysyłanie

ten kod Message pozwala mi wysłać wiadomość do członków zespołu projektu. Zespół użytkowników nie będzie otrzymywać wiadomości od oddzielnego zespołu użytkowników.

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"); 
    } 
    } 
} 
Powiązane problemy