除非您在客户端上设置一些事件来通知服务器窗口正在关闭,否则服务器将无法知道会话不再使用。
您需要在头脑中将会议视为两个部分。一部分是在节点和浏览器之间传递的令牌(cookie)。第二个是存储中会话的实际持久性(基本 MemoryStore 或 Redis,或者另一个数据库的新会话存储)。所有连接会话代码所做的就是将这些与每个请求进行匹配。
- 检查会话 cookie
- 如果存在,请尝试在商店中查找
- 使从存储中检索到的数据可用于请求
- 请求结束时,更新cookie的TTL信息
- 将会话写回存储
请注意,除非您使用 MemoryStore,否则 Node 不会在内存中保存会话数据,除非您的请求正在对其进行操作。 (嗯,它会在内存中保存一段时间,但不会被引用并受到垃圾收集)。当您考虑各种部署场景时,这是有道理的。
因此,服务器端会话过期的工作就落到了 Store 本身身上。 Redis 在这方面表现出色的原因之一是它可以自动管理过期的内容,您可以看到connect-redis
doing 在其集合操作中 https://github.com/visionmedia/connect-redis/blob/master/lib/connect-redis.js#L145:
RedisStore.prototype.set = function(sid, sess, fn){
sid = this.prefix + sid;
try {
var maxAge = sess.cookie.maxAge
, ttl = this.ttl
, sess = JSON.stringify(sess);
ttl = ttl || ('number' == typeof maxAge
? maxAge / 1000 | 0
: oneDay);
debug('SETEX "%s" ttl:%s %s', sid, ttl, sess);
this.client.setex(sid, ttl, sess, function(err){
err || debug('SETEX complete');
fn && fn.apply(this, arguments);
});
} catch (err) {
fn && fn(err);
}
};
您可以看到它将 TTL 除以 1000,因为它使用秒而不是毫秒作为过期时间。这最受欢迎的 MongoDB 会话 https://www.npmjs.org/package/connect-mongostore 以同样的方式使用 MongoDB 的 TTL 功能。
因此,这是一种很长的说法,您要么依赖数据库引擎自动提供服务器端会话过期,要么需要自己实现过期。您可以在节点应用程序外部有一个进程(可能是另一个节点进程)来执行此操作,或者您的商店实现可以安装 SetInterval 任务来定期检查和清理它。举个例子,一个基于 MySQL 的会话存储就是这么做的 https://github.com/nlf/connect-mysql/blob/master/lib/connect-mysql.js#L80
关于你问题的第二部分,什么是length
and clear
正在做?评论者是正确的,RedisStore 没有实现这些,并且可以安全地忽略它们,但是您可以在内存存储源代码 https://github.com/expressjs/session/blob/master/session/memory.js。不太令人兴奋。
clear
如果提供了回调,则清空所有会话和回调:
MemoryStore.prototype.clear = function(fn){
this.sessions = {};
fn && fn();
};
length
只需回调商店中的会话数即可:
MemoryStore.prototype.length = function(fn){
fn(null, Object.keys(this.sessions).length);
};
希望这有帮助。