2013-08-18 5 views
16

Было очень просто настроить сеансы и использовать их в php. Но мой веб-сайт должен иметь дело с веб-сайтами. Я столкнулся с проблемой настройки сеансов в node.js. Я могу легко переносить данные, не используя сеансы, и это будет работать нормально, но когда открыта более одной вкладки, новый сокет будет создан, а ранее открытые вкладки будут работать нормально. Поэтому я работал над сессиями и имел проблемы с доступом к sessionstore, его сеанс регистрации не был схвачен. Я тоже пробовал с session.load, но не повезлоexpress.session.MemoryStore не возвращает сеанс?

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

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!'); 
}); 
+1

Я думаю, мы должны отслеживать socket.id, но я не думаю, что это правильное решение. – user2626445

+0

Можете ли вы сказать немного больше о поведении, которое вы хотите после открытия новых вкладок? Вы хотите, чтобы они действовали как совершенно новый клиент, или вы хотите, чтобы они делили один и тот же сеанс? – leorex

+3

Есть ли у «err' что-нибудь? Или это '! Session', который говорит вам, что сеанса нет? – hexacyanide

ответ

1

Посмотрите на эту статью: Session-based Authorization with Socket.IO

Ваш код работает отлично, но нужно 2 улучшений, чтобы сделать то, что вы хотите (отправить данные сеанса для клиентов с сервера):

  1. его выдержки sessionID в течение авторизация только
  2. извлекает данные сессии из магазина этим sessionID в течение c onnection, где вы можете пересылать данные с сервера на клиентов в интервале.

Вот усовершенствованный код:

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>