.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 ...
随机推荐
- hdu1814
题解: 2-sat nm暴力 虽然似乎复杂度最低 代码: #include<cstdio> #include<cmath> #include<algorithm> ...
- 利用Appium Python测试爱壁纸的登录和设置壁纸
设置壁纸: #coding:utf-8 #Import the common package import os import unittest from appium import webdrive ...
- python中sort()与sorted()的区别
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...
- eclipsec常用快捷键
Eclipse常用快捷键 1几个最重要的快捷键 代码助手:Ctrl+Space(简体中文操作系统是Alt+/)快速修正:Ctrl+1单词补全:Alt+/打开外部Java文档:Shift+F2 显示搜索 ...
- SAPUI5实例一:来创建Web应用UI
试试SAPUI5.这是SAP比较重要的一个UI库.完全通过HTML5实现,可以作为Web和移动应用的UI开发. 现在已经开源了.在这里可以下载: http://sap.github.io/openui ...
- OC中使用单例模式
static Config * instance = nil; +(Config *) Instance { @synchronized(self) { if(nil == instance) { [ ...
- ASP.NET WebForm 与 IE10、IE11
最近维护公司一个烂项目.NET4.0 Asp.Net WebForm(在MVC5泛滥的今天还有用WebForm的(⊙o⊙)…) IE10.IE11下aspx中大表单提交不上去,报_DoPostBack ...
- skywalking探针tomcat8.0.28报错解决
在部署skywalking agent的时候遇到一个异常 环境如下: tomcat8.0.28 catalina.out 日志报如下错误 30-Apr-2019 10:25:57.664 INFO [ ...
- CF 148D D. Bag of mice (概率DP||数学期望)
The dragon and the princess are arguing about what to do on the New Year's Eve. The dragon suggests ...
- 页面提交 string数组和list对象集合举例
ajax表单提交 $.ajax({ cache: true, type: "POST", ...