express.session.MemoryStore не връща сесия?

Беше наистина лесно да настроите сесии и да ги използвате в PHP. Но моят уебсайт трябва да работи с WebSockets. Изправен съм пред проблем да настроя сесии в node.js. Мога лесно да изтласквам данни, без да използвам сесии и ще работи добре, но когато се отвори повече от един раздел, се създава нов socket.id и отворените преди това раздели няма да функционират правилно. Така че работих върху сесии и имах проблем с достъпа до магазина за сесии, сесията му за регистриране не беше хваната. Опитах и ​​с session.load, но без успех

Как да получа обект на сесия и да го използвам по начин, по който отварянето на други раздели да не повлияе на функционалността и да изтласква данни от сървър към клиент на всички раздели?

var express=require('express');
var http = require('http');
var io = require('socket.io');
var cookie = require("cookie");
var connect = require("connect"),
MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();

var app = express();

app.configure(function () {
    app.use(express.cookieParser());
    app.use(express.session({store: sessionStore
        , secret: 'secret'
        , key: 'express.sid'}));
    app.use(function (req, res) {
        res.end('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
    });
});

server = http.createServer(app);
server.listen(3000);

sio = io.listen(server);

var Session = require('connect').middleware.session.Session;

sio.set('authorization', function (data, accept) {
    // check if there's a cookie header
    if (data.headers.cookie) {
        // if there is, parse the cookie
        data.cookie = connect.utils.parseSignedCookies(cookie.parse(data.headers.cookie),'secret');
        // note that you will need to use the same key to grad the
        // session id, as you specified in the Express setup.
        data.sessionID = data.cookie['express.sid'];
        sessionStore.get(data.sessionID, function (err, session) {
            if (err || !session) {
                // if we cannot grab a session, turn down the connection
                console.log("session not grabbed");
                accept('Error', false);
            } else {
                // save the session data and accept the connection
                console.log("session grabbed");
                data.session = session;
                accept(null, true);
            }
        });
    } else {
       // if there isn't, turn down the connection with a message
       // and leave the function.
       return accept('No cookie transmitted.', false);
    }
    // accept the incoming connection
    accept(null, true);
});

sio.sockets.on('connection', function (socket) {
    console.log('A socket with sessionID ' + socket.handshake.sessionID 
        + ' connected!');
});

person user2626445    schedule 18.08.2013    source източник
comment
Предполагам, че трябва да следим socket.id, но не мисля, че това е правилното решение   -  person user2626445    schedule 13.12.2013
comment
Можете ли да кажете малко повече за поведението, което искате след отваряне на нови раздели? Искате ли те да се държат като напълно нов клиент, или искате да споделят една и съща сесия?   -  person leorex    schedule 15.12.2013
comment
err има ли нещо? Или !session ви казва, че няма сесия?   -  person hexacyanide    schedule 16.12.2013
comment
session и err са undefined. Но sessionStore има данни за всички потребителски сесии   -  person mrsrinivas    schedule 16.12.2013
comment
Открих подобен проблем [stackoverflow.com/questions/8863644/ Опитвали ли сте го някога? [1]: stackoverflow.com/questions/8863644/   -  person Moch Lutfi    schedule 18.12.2013


Отговори (1)


Разгледайте тази статия: Упълномощаване, базирано на сесия с Socket.IO

Вашият код работи добре, но се нуждае от 2 подобрения, за да прави това, което искате (изпращане на данни за сесията до клиентите от сървъра):

  1. той извлича sessionID само по време на упълномощаване
  2. той извлича данни за сесията от хранилището от този sessionID по време на връзка, където можете да изпращате данни от сървъра към клиентите през определен интервал.

Ето подобрения код:

var express = require('express');
var connect = require('connect');
var cookie = require('cookie');
var sessionStore = new express.session.MemoryStore();    

var app = express();    

app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({store: sessionStore, secret: "secret", key: 'express.sid'}));
// web page
app.use(express.static('public'));    

app.get('/', function(req, res) {
  var body = '';
  if (req.session.views) {
    ++req.session.views;
  } else {
    req.session.views = 1;
    body += '<p>First time visiting? view this page in several browsers :)</p>';
  }
  res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
});    

var sio = require('socket.io').listen(app.listen(3000));   

sio.set('authorization', function (data, accept) {
    // check if there's a cookie header
    if (data.headers.cookie) {
        // if there is, parse the cookie
        var rawCookies = cookie.parse(data.headers.cookie);
        data.sessionID = connect.utils.parseSignedCookie(rawCookies['express.sid'],'secret');    
        // it checks if the session id is unsigned successfully
        if (data.sessionID == rawCookies['express.sid']) {
            accept('cookie is invalid', false);
        }
    } else {
       // if there isn't, turn down the connection with a message
       // and leave the function.
       return accept('No cookie transmitted.', false);
    }
    // accept the incoming connection
    accept(null, true);
});    

sio.sockets.on('connection', function (socket) {
    //console.log(socket);
    console.log('A socket with sessionID ' + socket.handshake.sessionID + ' connected!');
    // it sets data every 5 seconds
    var handle = setInterval(function() {
        sessionStore.get(socket.handshake.sessionID, function (err, data) {
            if (err || !data) {
                console.log('no session data yet');
            } else {
                socket.emit('views', data);
            }
        });
    }, 5000);    

    socket.on('disconnect', function() {
        clearInterval(handle);
    });
});

След това можете да имате клиентска страница под public/client.html на http://localhost:3000/client.html, за да видите данните за сесията, попълнени от http://localhost:3000:

<html>
<head>
    <script src="/socket.io/socket.io.js" type="text/javascript"></script>
    <script type="text/javascript">
        tick = io.connect('http://localhost:3000/');
        tick.on('data', function (data) {
            console.log(data);
        });

        tick.on('views', function (data) {
            document.getElementById('views').innerText = data.views;
        });

        tick.on('error', function (reason){
          console.error('Unable to connect Socket.IO', reason);
        });

        tick.on('connect', function (){
          console.info('successfully established a working and authorized connection');
        });
    </script>
</head>
<body>
    Open the browser console to see tick-tocks!
    <p>This session is viewed <b><span id="views"></span></b> times.</p>
</body>

person shawnzhu    schedule 20.12.2013