Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NodeJS对session的简单封装 #10

Open
EchoFUN opened this issue Oct 29, 2013 · 3 comments
Open

NodeJS对session的简单封装 #10

EchoFUN opened this issue Oct 29, 2013 · 3 comments

Comments

@EchoFUN
Copy link
Owner

EchoFUN commented Oct 29, 2013

Session是神马?
百度百科(百度最有价值的产品)上的解释是
“在计算机专业术语中,session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间。”
通俗的讲,就是服务器端一段记录当前访问用户的空间。客户端的则是cookie,因为http协议无状态的特性,所以session的存在则必须依托于cookie。
前段时间打算搞个NodeJS的简单框架来支持WALNUT的后台的。突然发现NodeJS神马的,连个session也没有,提供给一次请求的参数就是http. ServerResponse和http.ClientRequest实例化出来的对象。充满幻想的我顿时内牛满面 … …
只好自己动手丰衣足食了。
服务器端必须在客户端使用cookie,可以在返回的头文件中设置,使用http.ServerResponse类中的:

response.setHeader('Set-Cookie', ['SID=' + sID]);

再通过每次获得客户端传来的cookie的,取出存放在服务器端对应session的方式,则可以很简单的模拟出session的效果。
如果不存在则新建一个session,代码如下所示:

var parse = require('querystring').parse;

/**
 * @description 设置session过期时间
 */
var EXPIRE_TIME = 3 * 60 * 1000;

/**
 * @description 存放服务器端所有session
 */
var _sessions = {};

function genSID(pre) {
  pre = (pre)?pre : 'SESSION';
  var time = new Date().getTime() + '';
  var id = pre + '_' + (time).substring(time.length - 6) + '_' + (Math.round(Math.random() * 1000));
  return id;
}

/**
 * @description 定时清理过期的session
 */
setInterval(function(){
  for (var id in _sessions) {
    if (!_sessions.hasOwnProperty(id)) 
      continue;
    if (new Date() - _sessions[id].timestamp > EXPIRE_TIME)
      delete _sessions[id];
    }
}, 1000);

var createSession = function(sID) {
  var session = {
    SID: sID,
    timestamp: new Date()
  }
  return session;
}

/**
 * @description 维护了对session的引用,可进行增删查改操作
 * @param {string} sID 当前用户的session ID
 * @param {object} _sessions
 */
var context = function(_sessions, sID) {
  this.poke = function() {
    _sessions[sID].timestamp = new Date();
  };
  this.destory = function() {
    delete _sessions[sID];
  };
  this.del = function(key) {
    this.poke();
    delete _sessions[sID][key];
  }
  this.set = function(key, value) {
    this.poke();
    _sessions[sID][key] = value;
  };
  this.get = function(key) {
    this.poke();
    return _sessions[sID][key];
  };
}

/**
 * @description 开始session
 * @param {object} request 
 * @param {object} response
 * @param {function} process 回调函数
 */
exports.startSession = function(request, response, process) {
  var cookies = parse(request.headers.cookie, '; ');
  var sID;
  for (var i in cookies) {
    if (i == 'SID') {
      sID = cookies[i];
      break;
    }
  }
  if (!sID || typeof _sessions[sID] == 'undefined') {
    var sID = genSID();
    _sessions[sID] = createSession(sID);
  }
  response.setHeader('Set-Cookie', ['SID=' + sID]);
  process.call(new context(_sessions, sID), request, response);
}

测试代码,主程序:

var http = require('http');
var sessionFactory = require('./session');

var server = http.createServer(function(request, response) {
  sessionFactory.startSession(request, response, handler);
});

var handler = function(request, response) {
  var session = this;
  session.set('banana', '你个巴啦~');
  response.end(session.get('banana'));
}

server.listen('80');

OK.
写在最后:
NodeJS,语言既是服务器,服务器既是语言的,这种方式很特别。想当初,nginx,apache的设计,就是为了把应用服务器和应用给分开来。这样的设计究竟是进步了还是倒退了,嗯~ 不好说。
总而言之,其实也无所谓啦!存在即合理,适合的就是最好的。
转载请注明出处
botobe.net
本文Github链接

2011.12.6,一切安好。
Merci !

@tiandaox
Copy link

nice.

@nimoc
Copy link

nimoc commented Dec 11, 2014

赞一个

适合的就是最好的
对于前端来说 node 实在是太赞了

@21k
Copy link

21k commented Jan 12, 2018

''><textarea>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants