Asp.net 实现Session分布式储存(Redis,Mongodb,Mysql等) sessionState Custom

本文介绍了ASP.NET中Session的工作原理,并重点讲解如何通过SessionStateStoreProviderBase实现Session的分布式存储,例如使用Redis、MongoDB或MySQL。文章还提供了利用SQLServer作为演示的代码实现,并分享了GitHub代码仓库链接。
摘要由CSDN通过智能技术生成
对于asp.net 程序员来说,Session的存储方式有InProc、StateServer、SQLServer和Custom,但是Custom确很少有人提及。但Custom确实最好用,目前最实用和最灵活一种方式,因为Custom可以实现各种情况的Session存储,特别对于大型网站尤为重要,解决Session丢失和Session效率的最佳实现方式,也是实现单点登录的最佳途径。 对于InProc、StateServer和SQLServer各自优缺点,网上一大堆,这里就不做详解。

 

重要的两点

 1、首先是关于Session存储,Session的存储并不是我们想象的,当设置Session时立即往数据容器里插入或者修改数据,当获取Session的值时就是立即去数据容器里获取值,这种理解是错误的(我之前就是这样理解的)。后来想想完全没必要这样操作,而且会大大影响效率。Asp.net的Session实现方式是每次请求前获取数据,当请求逻辑代码结束的时候在设置Session的值,所以说Session对数据容器的修改简单的意义只有两次,这个可能就要牵扯到管道流了。

2、第二个就是关于Asp.net网站异步的问题,当我们不设置Session的状态为只读时,我们每个用户的请求其实都是同步的,也就说每个用户请求网站同时只能有一个请求响应。理解这个就可以理解后面实现方法中需要锁的概念了。

 

SessionStateStoreProviderBase

  SessionStateStoreProviderBase是asp.net框架为我们提供的一个用来存储Session提供程序所需的成员(就是实现这个类),我们知道的InProc、SQLServer、StateServer都是实现了这个抽象类。继承这个类需要有多个抽象方法需要实现。关于这多个方法没必要每个都实现,我们只关注我们需要实现的即可。说简单点就是对Session数据的增删改查(CRUD)。关于SessionStateStoreProviderBase的详情可以参考https://msdn.microsoft.com/zh-cn/library/system.web.sessionstate.sessionstatestoreproviderbase(v=vs.100).aspx

 

成员

说明

InitializeRequest 方法

采用当前请求的 HttpContext 实例作为输入,并执行会话状态存储提供程序必需的所有初始化操作。

EndRequest方法

采用当前请求的 HttpContext 实例作为输入,并执行会话状态存储提供程序必需的所有清理操作。

Dispose 方法

释放会话状态存储提供程序不再使用的所有资源。

GetItemExclusive 方法

采用当前请求的 HttpContext 实例和当前请求的 SessionID 值作为输入。从会话数据存储区中检索会话的值和信息,并在请求持续期间锁定数据存储区中的会话项数据。GetItemExclusive 方法设置几个输出参数值,这些参数值将数据存储区中当前会话状态项的状态通知给执行调用的 SessionStateModule

如果数据存储区中未找到任何会话项数据,则 GetItemExclusive 方法将 locked 输出参数设置为 false,并返回 null。这将导致SessionStateModule 调用 CreateNewStoreData 方法来为请求创建一个新的 SessionStateStoreData 对象。

如果在数据存储区中找到会话项数据但该数据已锁定,则 GetItemExclusive 方法将 locked 输出参数设置为 true,将 lockAge输出参数设置为当前日期和时间与该项锁定日期和时间的差,将 lockId 输出参数设置为从数据存储区中检索的锁定标识符,并返回 null。这将导致 SessionStateModule 隔半秒后再次调用 GetItemExclusive 方法,以尝试检索会话项信息和获取对数据的锁定。如果 lockAge 输出参数的设置值超过 ExecutionTimeout 值,SessionStateModule 将调用 ReleaseItemExclusive 方法以清除对会话项数据的锁定,然后再次调用 GetItemExclusive 方法。

如果 regenerateExpiredSessionId 属性设置为 true,则 actionFlags 参数用于其 Cookieless 属性为 true 的会话。actionFlags 值设置为 InitializeItem (1) 则指示会话数据存储区中的项是需要初始化的新会话。通过调用CreateUninitializedItem 方法可以创建会话数据存储区中未初始化的项。如果会话数据存储区中的项已经初始化,则actionFlags 参数设置为零。

如果提供程序支持无 Cookie 会话,请将 actionFlags 输出参数设置为当前项从会话数据存储区中返回的值。如果被请求的会话存储项的 actionFlags 参数值等于 InitializeItem 枚举值 (1),则 GetItemExclusive 方法在设置 actionFlags out 参数之后应将数据存储区中的值设置为零。

GetItem 方法

除了不尝试锁定数据存储区中的会话项以外,此方法与 GetItemExclusive 方法执行的操作相同。GetItem 方法在EnableSessionState 属性设置为 ReadOnly 时调用。

SetAndReleaseItemExclusive 方法

采用当前请求的 HttpContext 实例、当前请求的 SessionID 值、包含要存储的当前会话值的 SessionStateStoreData 对象、当前请求的锁定标识符以及指示要存储的数据是属于新会话还是现有会话的值作为输入。

如果 newItem 参数为 true,则 SetAndReleaseItemExclusive 方法使用提供的值将一个新项插入到数据存储区中。否则,数据存储区中的现有项使用提供的值进行更新,并释放对数据的任何锁定。请注意,只有与提供的 SessionID 值和锁定标识符值匹配的当前应用程序的会话数据才会更新。

调用 SetAndReleaseItemExclusive 方法后,SessionStateModule 调用 ResetItemTimeout 方法来更新会话项数据的过期日期和时间。

ReleaseItemExclusive 方法

采用当前请求的 HttpContext 实例、当前请求的 SessionID 值以及当前请求的锁定标识符作为输入,并释放对会话数据存储区中的项的锁定。在调用 GetItem 或 GetItemExclusive 方法,并且数据存储区指定被请求项已锁定,但锁定时间已超过ExecutionTimeout 值时会调用此方法。此方法清除锁定,释放该被请求项以供其他请求使用。

RemoveItem方法

采用当前请求的 HttpContext 实例、当前请求的 SessionID 值以及当前请求的锁定标识符作为输入,并删除数据存储区中与提供的 SessionID 值、当前应用程序和提供的锁定标识符相匹配的数据存储项的会话信息。此方法在 Abandon 方法被调用时调用。

CreateUninitializedItem方法

采用当前请求的 HttpContext 实例、当前请求的 SessionID 值以及当前请求的锁定标识符作为输入,并向会话数据存储区添加一个 actionFlags 值为 InitializeItem 的未初始化项。

如果 regenerateExpiredSessionId 属性设置为 true,则 CreateUninitializedItem 方法用于无 Cookie 会话,这将导致遇到过期会话 ID 时,SessionStateModule 会生成一个新的 SessionID 值。

生成新的 SessionID 值的过程需要浏览器重定向到包含新生成的会话 ID 的 URL。在包含过期的会话 ID 的初始请求期间,会调用CreateUninitializedItem 方法。SessionStateModule 获取一个新的 SessionID 值来替换过期的会话 ID 之后,它会调用CreateUninitializedItem 方法以将一个未初始化项添加到会话状态数据存储区中。然后,浏览器重定向到包含新生成的SessionID 值的 URL。如果会话数据存储区中存在未初始化项,则可以确保包含新生成的 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值