.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 ...
随机推荐
- CSS技巧和经验
如何清除图片下方出现几像素的空白间隙 方法1 img { display: block; } 方法2 除了top值,还可以设置为text-top | middle | bottom | text-bo ...
- Centos6安装MariaDB-yum方式
1.创建安装目录: mkdir /data/mysql/ mkdir /data/mysql/datafile mkdir /data/mysql/logfile 2.创建用户: useradd -r ...
- HDU 4549 M斐波那契数列(矩阵快速幂+费马小定理)
M斐波那契数列 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submi ...
- Git 分布式版本控制的常见命令
Git 的作用: (1)方便多人协同开发; (2)方便版本控制 Git 分布式版本控制的主要区域及命令图,下面会详细讲解: 创建项目并将切换至项目目录下 1. 创建本地仓库: git init ...
- jfreechart在jsp中画图方式
这个问题一直困扰我好久,今天算是稍微找到一点解决思路了,在网上搜了好多列子,大部分的都是用servlet来实现画图,偶然找到一个列子用的是org.jfree.chart.servlet.Servlet ...
- 使用jQuery操作DOM(1)
1.常见方法 css(“属性”,”属性值”); //设置单个样式 css({属性1:属性值1,属性2:属性值3...}); //设置多个样式 addClass(“样式名”); //追加单个样式 add ...
- Makefile特殊标签
http://www.gnu.org/software/make/manual/html_node/Special-Targets.html
- R︱Yandex的梯度提升CatBoost 算法(官方述:超越XGBoost/lightGBM/h2o)
俄罗斯搜索巨头 Yandex 昨日宣布开源 CatBoost ,这是一种支持类别特征,基于梯度提升决策树的机器学习方法. CatBoost 是由 Yandex 的研究人员和工程师开发的,是 Matri ...
- Shell 批量搜索关键词并保存结果到文件中(数组、循环)
#!/bin/bash keywords=("不需要" "不用谢谢" "xxx" "xxx") for var in $ ...
- java android 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...