.NET实现多个不同有效时间Session方案思考
什么是Session?简单讲,Session是一种服务端用于保存每个客户端用户的状态信息的机制。客户端第一次访问时,服务端从分配一个空间专门存储该客户端的信息,后续访问时便可以直接获取或者更新状态信息。具体关于Session定义请查看参考。
.NET下Session使用很简单,对写入Session值无类型限制,设置Session有效时间也很简单,直接设置Session的timeout属性即可,类型为int,单位为分钟。
Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss");
Session.Timeout = ;
但若要设置多个有效时间不同的Session,就不那么友好了,后设置的有效时间会覆盖之前值。
//写入用户登录状态到Session。
Session["state"] = "On";
//设置用户登录状态有效时间为1天,除非登录清空Session,否则整天登录状态有效。
Session.Timeout = * ; //设置类似验证码类似的session,假设有效时间为1分钟。
Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss");
Session.Timeout = ;
原因在于C#中只提供了session有效时间统一设置方法,无法对单个session进行有效时间进行设置。
因此要在服务端对多个session分别设置有效时间就只能另辟蹊径,可以采用的方法大致分为两类:
- 基于session机制进行扩展,通过扩展方法实现,即方案1和方案3。目前并没有从博客园或者相关文献中找到方案,唯一找到的参考资料方案3中有提及。
- 考虑使用redis等替代session功能,redis允许对特定键值对设置有效时间,方案2。该类型的方案较多,博客园各位大大都有文献介绍,所以本文重点不在这里。
方案1:构建结构为: Tuple.Create<string, object, int>(key, value, time) 的tuple元组,将tuple写入Session中。
写入时根据传入有效时间计算出过期时间,将过期时间存入,获取Session时判断是否已经超过过期截止时间,超过返回空,并且清空Session。
private void SetSingleSession(string key, object value, int? timeout)
{
int time = timeout ?? Session.Timeout;
DateTime endTime = DateTime.Now + new TimeSpan(,time,);
var tuple = Tuple.Create(key, value, endTime);
Session[key] = tuple;
}
private object GetSingleSession(string key)
{
var tuple = Session[key] as Tuple<string, object, DateTime>;
var diff = DateTime.Compare(tuple.Item3, DateTime.Now);
object result = null;
if (diff > ) result = tuple.Item2;//有效时间截止之前正常返回值
else Session.Remove(key);//超过有效时间清空Session
return result;
}
方案2:使用Redis。
- 安装redis服务。windows版:https://github.com/MSOpenTech/redis/release,下载安装包并点击安装,直到安装完成。
设置登录密码,打开cmd窗口,输入“cd C:\Program Files\redis”进入redis安装目录,输入“redis-cli.exe”运行该exe程序,继续输入 “config pass requirepass password”(password改为要设置的登录密码),完成密码设置。
- Nuget中安装“StackExchange.Redis”.
- redis使用,基础代码如下。
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379,password=fxy123");
IDatabase db = redis.GetDatabase();
//写入记录,包括有效时间:10秒过期
db.StringSet ( "key_test" , "shaocan",TimeSpan.FromSeconds());
方案3:通过扩展Session类,设置一个异步延迟执行机制,定时清除session。(原始文献参考ASP.NET Session: Caching Expiring Values)
public static class SessionHelper
{
public static void AddWithTimeout(this HttpSessionStateBase session,string name,object value,int? minute)
{
TimeSpan timeSpan=TimeSpan.FromMinutes(minute??session.TimeOut);
lock (session)
{
session[name] = value;
}
Task.Delay(expireAfter).ContinueWith((task) => {
lock (session)
{
session.Remove(name);
}
});
}
}
如果不是特别庞大的项目,推荐使用方案三,简单扩展方法即可实现,只需设置时使用Session扩展方法即可;对于比较大的项目,推荐使用方案2进行管理,毕竟Session机制由于服务器重启等原因会丢失,造成用户体验不佳。不推荐使用方案1,如果使用方案1设置和获取session都必须采用该扩展类进行,否则会存在过期但并未失效的情况。
如果您觉得本文有参考价值或者不足之处,请留下您的建议。谢谢。
.NET实现多个不同有效时间Session方案思考的更多相关文章
- 可扩容分布式session方案
分布式session有以下几种方案: 1. 基于nfs(net filesystem)的session共享 将共享服务器目录mount各服务器的本地session目录,session读写受共享服务器i ...
- 基于nginx的频率控制方案思考和实践
基于nginx的频率控制方案思考 标签: 频率控制 nginx 背景 nginx其实有自带的limit_req和limit_conn模块,不过它们需要在配置文件中进行配置才能发挥作用,每次有频控策略的 ...
- [Node.js] Node + Redis 实现分布式Session方案
原文地址: http://www.moye.me/?p=565 Session是什么? Session 是面向连接的状态信息,是对 Http 无状态协议的补充. Session 怎么工作? Sessi ...
- 分布式存储Memcache替代Session方案
PHP自带的Session实际是在服务器中为每个客户建立独立的文件存放各自的信息. 在不做处理的情况下,很容易被客户端伪造.并且由于采用文件形式,所以存在着IO 读写的瓶颈.一般当用户在线达到1000 ...
- 一篇文章让你深透理解cookie和session,附带分布式WEB系统redis共享session方案
cookie和session有什么区别?这是一个很基础的知识点,大家可能都知道一个大概:cookie是存在客户端的,session是存储在服务端,cookie和session用来验证识别用户的登录状态 ...
- Node + Redis 实现分布式Session方案(转载)
Session是什么? Session 是面向连接的状态信息,是对 Http 无状态协议的补充. Session 怎么工作? Session 数据保留在服务端,而为了标识具体 Session 信息指向 ...
- Tomcat7.0.99集群使用Redis共享session方案
以前配置过给予多播的session共享方案,这回再配置一个redis共享session的. 先小小的炫耀一下: 相信大家要做Tomcat+Redis+session配置,遇到的头号麻烦就是编译的tom ...
- PHP cookie禁用时session 方案
在PHP中使用过SESSION的朋友可能会碰到这么一个问题,SESSION变量不能跨页传递.这令我苦恼了好些日子,最终通过查资料思考并解决了这个问题.我认为,出现这个问题的原因有以下几点: 1.客户端 ...
- Apache Shiro 用户信息保存在session方案
描述 在使用shiro的时候,经常会有一种需求: 把登录成功后的用户对象存放到session中,方面其他地方调用.存放到session这个步骤到底应该在哪里去做,有几个地方比较合适: 调用 Subje ...
随机推荐
- 【nynu】 妹妹的工资怎么算(二分)
题目链接:http://47.93.252.151/problem.php?id=1148 题目描述 <我的妹妹哪有这么可爱!>中的女主叫做高坂桐乃,高坂家的幺女,外表出众.成绩优秀.运动 ...
- 决定整理一下canvas的基础学习
好久没有用过canvas,都要忘完了.还是决定复习一下以前的笔记,以及整理一下笔记,以后好查阅
- 【Seajs源码分析】2. 工具方法1
Sea.js: var seajs = global.seajs = { // The current version of Sea.js being used version: "@VER ...
- PHP 中使用explode()函数切割字符串为数组
explode()函数的作用:使用一个字符串分割另一个字符串,打散为数组. 例如: 字符串 $pizza = "第1 第2 第3 第4 第5 第6"; 根据空格分割后:$piece ...
- flask框架中勾子函数的使用
在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接: 在请求开始时,根据需求进行权限校验: 在请求结束时,指定数据的交互格式: 为了让每个视图函数避免编 ...
- mysql报错注入手工方法
以前觉得报错注入有那么一长串,还有各种concat(),rand()之类的函数,不方便记忆和使用,一直没怎么仔细的学习过.这次专门学习了一下,看了一些大牛的总结,得到一些经验,特此记录下来,以备后续巩 ...
- flowable IdmEngine和IdmEngineConfiguration
IdmEngineConfiguration 继承了 AbstractEngineConfiguration. 一.创建EngineConfiguration实例 IdmEngineConfigura ...
- HAWQ + MADlib 玩转数据挖掘之(一)——安装
一.MADlib简介 MADlib是Pivotal公司与伯克利大学合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器学习方法对结构化和非结构化数据进行分析,主要目的是扩展数据库的分析能力, ...
- 使用微软T4 template进行代码生成
使得软件工程高效开发的主要方法是复用.复用的宗旨是提高设计的内聚性,主要包括:函数,类,模式,组件,框架等等.而有些应用场景并都是可以直接拿来现成代码使用的,有时代码库的代码不是那么容易修改,或者根本 ...
- 【剑指offer】左旋转字符串,C+实现
原创博文,转载请注明出处! 本题牛客网地址 本题代码的github地址 本系列文章的索引地址 # 题目 # 思路 先局部翻转,后整体翻转.举例:abcdefg先局部翻转为bagfedc,后整体翻转为c ...