2016-01-15 21 views
10

Sto utilizzando Socket.io in un'applicazione di chat che sto creando. Sto cercando di impostare la sessione in modo da poter mantenere il login degli utenti tra una sessione e l'altra.Socket IO solo sessione non persistente

Ecco il codice rilevante:

index.js (server)

var cookieParser = require('cookie-parser')(); 
var session = require('cookie-session')({ secret: 'secret' }); 

app.use(cookieParser); 
app.use(session); 

io.use(function(socket, next) { 
    var req = socket.handshake; 
    var res = {}; 
    cookieParser(req, res, function(err) { 
     if (err) return next(err); 
     session(req, res, next); 
    }); 
}); 


io.on('connection', function(socket){ 

    socket.on('test 1', function(){ 
     socket.handshake.test = 'banana'; 
    }); 

    socket.on('test 2', function(){ 
     console.log(socket.handshake.test); 
    }); 
}); 

Chat.js (client)

var socket = io(); 

socket.emit('test 1'); 
socket.emit('test 2'); 

Il codice sopra funziona, lo farà stampare banana nella console come previsto. Tuttavia, se io commento la 'prova 1' in questo modo:

var socket = io(); 

// socket.emit('test 1'); 
socket.emit('test 2'); 

Si stamperà undefined alla console.

Non dovrebbe ancora essere in grado di stampare banana, poiché sta utilizzando una sessione ed è persistente tra le richieste? Incontro anche lo stesso problema se inverso l'ordine in cui chiamo "test 1" e "test 2".

Cosa sto sbagliando? Cosa mi manca perché la sessione continui come previsto?

+0

costa usare 'socket.handshake.session.test = 'banane';' 'test per 1' e' socket.handshake. session.test' per 'test 2' funziona? –

risposta

5

Il problema è che si sta utilizzando un cookie-session, e socket.io non consente di impostare i cookie causa specifica di XMLHttpRequest, anche non si dispone di un request/response nel bel mezzo di una transazione presa web, così non si può imposta il cookie di risposta.

Con il middleware, è possibile visualizzare i cookie, ma non è possibile impostarlo in socket.io. Questo può essere assicurato con questo esempio:

io.use(function(socket, next) { 
    var req = socket.request; 
    var res = req.res; 
    cookieParser(req, res, function(err) { 
     if (err) return next(err); 
     session(req, res, next); 
    }); 
}); 

io.on('connection', function(socket){ 
    var req = socket.request; 
    console.log(req.session.test) 

    socket.on('test 1', function(){ 
     req.session.test = 'banana'; 
    }); 

    socket.on('test 2', function(){ 
     console.log(req.session.test); 
    }); 
}); 

app.get('/', function(req, res) { 
    console.log(req.session.test) 
    if (!req.session.test) { 
     req.session.test = 'banana request' 
    } 
})  

È possibile usare qualcosa come redis a persistere le sessioni, o un po 'di Hack' per impostare nella stretta di mano.

Un'altra opzione non è affatto l'uso di sessioni e basta impostare la proprietà nell'oggetto socket o in un altro oggetto javascript, ma in questo caso non è possibile condividere l'oggetto tra server/servizi.

1
  1. C'è ancora accesso alle intestazioni.
  2. È possibile salvare i dati sul lato server per ciascun socket: socket.my_value = "qualsiasi tipo di dati";
  3. È possibile salvare i dati nell'oggetto io.sockets, io.my_value = "qualsiasi tipo di dati"

Così, ad esempio:

io.on('connection', function(socket){ 
     var id = socket.handshake.query.id; //you can set this in client connection string http://localhost?id=user_id 
     //Validate user, registered etc. and if ok/ 
     if(validateUser(id)) { 
      //if this is reconnect 
      if(io.sessions[id]) { 
       socket.session_id = io.sessions[id].session_id; 
      } else { 
       var session_id = random_value; 
       socket.session_id = some_random_value; 
       io.sessions[id] = { 
       user_id: id, 
       session_id: socket.session_id 
       }; 
      } 

      registerEvent(socket); 
     } else { 
      socket.emit('auth_error', 'wrong user'); 
     } 
    }); 


function registerEvent(socket) { 
    socket.on('some_event', function(data, callback) { 
     if(!socket.session_id) { 
     callback('unathorized');//or emit 
     socket.emit('auth_error', 'unauthorized'); 
     } 

     //do what you want, user is clear 
    }); 
}