2012-05-07 47 views
10

Mam śledzić ten przewodnik: http://www.danielbaulig.de/socket-ioexpress/, aby połączyć express.js do socket.io i działa wspaniale.Jak wykryć wiele połączeń socket.io z tego samego użytkownika?

Mam użytkownika logującego się na jednej stronie (żądanie POST express.js, które ustawia obiekt sesji), a po uwierzytelnieniu kieruje je do nowej strony, na której ładuje się plik socket.io i na serwerze socket.io chwyć sesję, która została ustawiona z wyrażenia. Że wszystko działa dobrze.

Teraz mam użytkowników na stronie, która używa socket.io i kiedy strona jest odświeżana - czasami połączenie socket.io nadal istnieje (tj. Nie rozłącza się). Co próbuję zrobić, to zmienić funkcję io.set('authorization'), aby upewnić się, że gdy użytkownik się połączy - rozłączy wszystkie istniejące wystąpienia socket.io, które są nadal otwarte dla tego klienta.

Oto jak to wygląda w tej chwili:

//socket.io connect to express 
var parseCookie = require('connect').utils.parseCookie; 
io.set('authorization', function (data, accept) { 
    if (data.headers.cookie) 
    { 
     data.cookie = parseCookie(data.headers.cookie); 
     data.sessionID = data.cookie['express.sid']; 
     // (literally) get the session data from the session store 
     sessionStore.get(data.sessionID, function (err, session) 
     { 
      if (err || !session) 
      { 
       // if we cannot grab a session, turn down the connection 
       //note: a session is created when the user logs in 
       accept('Error', false); 
      } 
      else 
      { 
       //TODO something here before we accept the connection 
       //?? 

       // save the session data 
       data.session = session; 
       //accept the connection 
       accept(null, true); 
      } 
     }); 
    } 
    else 
    { 
     return accept('No cookie transmitted.', false); 
    } 
}); 

Jak mogę sprawdzić, czy klient, który ma zostać przyjęty posiada poprzednie połączenie, a wciąż jest otwarty (a więc musimy odłącz to stare).

Sesja ekspresowa ma w nazwie "nazwę użytkownika" - dzięki czemu możemy uzyskać obiekt sesji i uzyskać nazwę użytkownika, po prostu nie mogę wymyślić, jak przejść przez listę wszystkich klientów socket.io i mieć spójrz na sesję ekspresową dla każdej z nich i sprawdź, czy jest taka sama, jak użytkownik uwierzytelniający się obecnie.

Odpowiedz

6

W mojej aplikacji jawnie zarządzam sesjami socket.io. Po stronie serwera, po ustanowieniu nowego połączenia, robię coś takiego: socketio_session[user_id].push(session). Daje mi to dostęp do wszystkich sesji połączonych z konkretnym użytkownikiem. W twoim przypadku nie musisz przechowywać listy sesji na użytkownika, ale tylko przechowywać ostatnią sesję i onconnect wymuszać rozłączenie w istniejącej sesji, jeśli jest, przed zapisaniem nowej sesji.

+0

Tak, to jest najprostsza opcja. Chociaż jestem pewien, że musi istnieć sposób na zrobienie tego za pomocą globalnej zmiennej socket.io. – Andrew

+0

Używam TornadIO2, w którym to przypadku nie ma żadnej wbudowanej takiej rzeczy (czytałem linię kodu źródłowego po linii). Ale jeśli używasz Node.js z socket.io na serwerze, to nie jestem pewien. –

+0

Tak, wygląda na to, że był to najprostszy sposób robienia rzeczy. Przechowuję teraz wszystkie połączenia w tablicy, więc mam do nich dostęp ... Pozdrawiam za to. – Andrew

0

Istnieje wiele kodu na Socket.IO jest stary.

Nowa dokumentacja (Socket.IO 1.3.6, teraz), mówi:

„Stary io.set() i io.get() metody są przestarzałe i obsługiwane tylko dla wstecznej kompatybilności tutaj. to tłumaczenie przykładowej autoryzacji w starym stylu na middleware. " w sekcji "Migracja z 0,9"

Jeśli używasz nowej wersji Socket.IO. Kod, którego potrzebujesz, to coś takiego:

var sessionStore = new MongoStore({ url: config.db }); 
    var cookie   = require('cookie-parser')("SECRET"); 
    io.use(function(socket, callback) { 
     if (socket.request.headers.cookie) { 
      cookie(socket.request, null, function(err) { 
       sessionStore.get(socket.request.signedCookies["connect.sid"], function(err, session) { 
        if (err || !session) { 
         callback('Session error', false); 
        } else { 
         socket.request.sessionID = socket.request.signedCookies["connect.sid"]; 
         console.log(socket.request.sessionID); 
         callback(null, true); 
        } 
        }); 
      }); 
     } 
     else { 
      return callback('No session.', false); 
     } 
    }); 
    io.on('connection', function(socket) { 
     console.log(socket.request.sessionID); 
    }); 
Powiązane problemy