博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET实现多个不同有效时间Session方案思考
阅读量:6800 次
发布时间:2019-06-26

本文共 3080 字,大约阅读时间需要 10 分钟。

  什么是Session?简单讲,Session是一种服务端用于保存每个客户端用户的状态信息的机制。客户端第一次访问时,服务端从分配一个空间专门存储该客户端的信息,后续访问时便可以直接获取或者更新状态信息。具体关于Session定义请查看。

  .NET下Session使用很简单,对写入Session值无类型限制,设置Session有效时间也很简单,直接设置Session的timeout属性即可,类型为int,单位为分钟。

1             Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss");2             Session.Timeout = 60;

  但若要设置多个有效时间不同的Session,就不那么友好了,后设置的有效时间会覆盖之前值

1             //写入用户登录状态到Session。2             Session["state"] = "On";3             //设置用户登录状态有效时间为1天,除非登录清空Session,否则整天登录状态有效。4             Session.Timeout = 60 * 24;5 6             //设置类似验证码类似的session,假设有效时间为1分钟。7             Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss");8             Session.Timeout = 1;

  原因在于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。

1         private void SetSingleSession(string key, object value, int? timeout)2         {3             int time = timeout ?? Session.Timeout;4             DateTime endTime = DateTime.Now + new TimeSpan(0,time,0);5             var tuple = Tuple.Create(key, value, endTime);6             Session[key] = tuple;7         }
1         private object GetSingleSession(string key)2         {3             var tuple = Session[key] as Tuple
;4 var diff = DateTime.Compare(tuple.Item3, DateTime.Now);5 object result = null;6 if (diff > 0) result = tuple.Item2;//有效时间截止之前正常返回值7 else Session.Remove(key);//超过有效时间清空Session8 return result;9 }

  方案2:使用Redis。

  • 安装redis服务。windows版:,下载安装包并点击安装,直到安装完成。
  • 设置登录密码,打开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(10));

 方案3:通过扩展Session类,设置一个异步延迟执行机制,定时清除session。(原始文献参考)

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都必须采用该扩展类进行,否则会存在过期但并未失效的情况。

  如果您觉得本文有参考价值或者不足之处,请留下您的建议。谢谢。

转载于:https://www.cnblogs.com/fuxuyang/p/8416578.html

你可能感兴趣的文章
webpack4+vue实现多页面,结合Hbuilder快速开发APP
查看>>
springCloud Finchley 微服务架构从入门到精通【八】断路器 Hystrix(feign)
查看>>
vue的axios组件如何与PHP后端交换数据
查看>>
Flutter教程(二) 了解Dart语言
查看>>
ES6 札记:let 和 const
查看>>
FCC 成都社区·前端周刊 第 8 期
查看>>
Ant Design Pro用小乌龟版的git提交时报错
查看>>
Laravel 中使用 puppeteer 采集异步加载的网页内容
查看>>
Python每日小知识(5):调用和定义函数
查看>>
Spring中使用ActiveMQ
查看>>
【数据结构】Java语言描述-循环链表和双向链表操作
查看>>
什么是跨域以及几种简单解决方案
查看>>
reactor-netty中TcpClient的create过程
查看>>
使用vue开发桌面应用(electron)
查看>>
pipenv 更优雅的管理你的python开发环境
查看>>
微信小程序生成二维码工具
查看>>
weex-android添加返回按钮监听
查看>>
Android精品源码,微信红包动画动画效果库输入框风格新闻客户端组件化方案...
查看>>
CSS相关文章
查看>>
Spark User-guide Summary - Streaming
查看>>