自定义会话状态存储提供程序

简介: 原文:自定义会话状态存储提供程序自定义会话状态存储提供程序    此版本程序只是说明  自定义会话  可以放在不同的地方, 可以改造成 把会话分布式存储 等。   一、Web.config              二、 JinshuaiCustomSessio...
原文: 自定义会话状态存储提供程序

自定义会话状态存储提供程序

 

 此版本程序只是说明  自定义会话  可以放在不同的地方, 可以改造成 把会话分布式存储 等。

 

一、Web.config 

<sessionState mode="Custom" customProvider="JinshuaiCustomSessionStateProvider">
  <providers>
       <add name="JinshuaiCustomSessionStateProvider" type="SessionStateWebApplication.Sessions.JinshuaiCustomSessionStateProvider" connectionStringName="DefaultConnection" />
</providers>
</sessionState>

 

二、 JinshuaiCustomSessionStateProvider 提供程序

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Collections.Specialized;
  4 using System.IO;
  5 using System.Linq;
  6 using System.Web;
  7 using System.Web.SessionState;
  8 
  9 namespace SessionStateWebApplication.Sessions
 10 {
 11     public class JinshuaiCustomSessionStateProvider : SessionStateStoreProviderBase
 12     {
 13         private static Dictionary<string, CustomSession> _dic = new Dictionary<string, CustomSession>();
 14 
 15         public string AppName
 16         {
 17             get { return "jinshuaiTest"; }
 18         }
 19 
 20         public int TimeOut { get; set; }
 21 
 22 
 23         public override void Initialize(string name, NameValueCollection config)
 24         {
 25             TimeOut = 20;
 26 
 27             base.Initialize(name, config);
 28         }
 29 
 30 
 31         public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
 32         {
 33             TimeOut = timeout;
 34             return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
 35         }
 36 
 37         public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
 38         {
 39             var newSession = new CustomSession
 40             {
 41                 SessionId = id,
 42                 LockDate = DateTime.Now,
 43                 Locked = false,
 44                 LockId = 0,
 45                 SessionItems = string.Empty,
 46                 Timeout = timeout,
 47                 Expires = DateTime.Now.AddMinutes(timeout),
 48                 Created = DateTime.Now,
 49                 ApplicationName = AppName
 50             };
 51             _dic.Add(id, newSession);
 52 
 53         }
 54 
 55         public override void Dispose()
 56         {
 57 
 58         }
 59 
 60         public override void EndRequest(HttpContext context)
 61         {
 62 
 63         }
 64 
 65         public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
 66         {
 67 
 68             return GetItemByExclusive(false, context, id, out locked, out lockAge, out lockId, out actions);
 69         }
 70 
 71         public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
 72         {
 73             return GetItemByExclusive(true, context, id, out locked, out lockAge, out lockId, out actions);
 74         }
 75 
 76 
 77 
 78         public SessionStateStoreData GetItemByExclusive(bool isExclusive, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
 79         {
 80             locked = false;
 81             lockAge = TimeSpan.Zero;
 82             lockId = null;
 83             actions = SessionStateActions.None;
 84 
 85             CustomSession tempSession = null;
 86 
 87 
 88             if (_dic.ContainsKey(id))
 89             {
 90                 tempSession = _dic[id];
 91             }
 92             else
 93             {
 94                 //没找到相应的会话
 95                 return null;
 96             }
 97 
 98             //如果过期
 99             if (tempSession.Expires <= DateTime.Now)
100             {
101                 _dic.Remove(id);
102                 return null;
103             }
104 
105 
106             //是否独占访问
107             if (isExclusive)
108             {
109                 if (tempSession.Locked)
110                 {
111                     locked = true;
112                     lockAge = (DateTime.Now - tempSession.LockDate);
113                     lockId = tempSession.LockId;
114                     actions = (SessionStateActions)tempSession.Flags;
115                     return null;
116                 }
117             }
118 
119             return Deserialize(context, tempSession.SessionItems, tempSession.Timeout);
120 
121         }
122 
123 
124 
125 
126 
127         public override void InitializeRequest(HttpContext context)
128         {
129 
130         }
131 
132         public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
133         {
134             if (!_dic.ContainsKey(id)) return;
135 
136             var tempSession = _dic[id];
137             tempSession.LockId = (int)(lockId??0);
138             tempSession.Locked = false;
139             tempSession.Expires = DateTime.Now.AddMinutes(tempSession.Timeout);
140         }
141 
142         public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
143         {
144 
145             if (!_dic.ContainsKey(id)) return;
146 
147             _dic.Remove(id);
148 
149         }
150 
151         public override void ResetItemTimeout(HttpContext context, string id)
152         {
153 
154             if (!_dic.ContainsKey(id)) return;
155 
156             var tempSession = _dic[id];
157             tempSession.Expires = DateTime.Now.AddMinutes(tempSession.Timeout);
158 
159         }
160 
161         public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
162         {
163 
164             string sessItems = Serialize((SessionStateItemCollection)item.Items);
165 
166             if (newItem)
167             {
168                 var newSession = new CustomSession
169                 {
170                     SessionId = id,
171                     LockDate = DateTime.Now,
172                     Locked = false,
173                     LockId = 0,
174                     SessionItems = sessItems,
175                     Timeout = TimeOut,
176                     Expires = DateTime.Now.AddMinutes(TimeOut),
177                     Created = DateTime.Now,
178                     ApplicationName = AppName
179                 };
180                 _dic.Add(id, newSession);
181 
182             }
183             else
184             {
185 
186                 if (!_dic.ContainsKey(id))
187                 {
188                     var newSession = new CustomSession
189                     {
190                         SessionId = id,
191                         LockDate = DateTime.Now,
192                         Locked = false,
193                         LockId = 0,
194                         SessionItems = sessItems,
195                         Timeout = TimeOut,
196                         Expires = DateTime.Now.AddMinutes(TimeOut),
197                         Created = DateTime.Now,
198                         ApplicationName = AppName
199                     };
200                     _dic.Add(id, newSession);
201 
202                 }
203 
204                 var tempSession = _dic[id];
205                 tempSession.Expires = DateTime.Now.AddMinutes(TimeOut);
206                 tempSession.SessionItems = sessItems;
207                 tempSession.LockId =(int)(lockId??0);
208                 tempSession.LockDate = DateTime.Now;
209 
210             }
211 
212 
213         }
214 
215         public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
216         {
217 
218             return false;
219         }
220 
221 
222 
223 
224 
225 
226 
227         private string Serialize(SessionStateItemCollection items)
228         {
229             MemoryStream ms = new MemoryStream();
230             BinaryWriter writer = new BinaryWriter(ms);
231 
232             if (items != null)
233                 items.Serialize(writer);
234 
235             writer.Close();
236 
237             return Convert.ToBase64String(ms.ToArray());
238         }
239 
240         private SessionStateStoreData Deserialize(HttpContext context,
241           string serializedItems, int timeout)
242         {
243             MemoryStream ms =
244               new MemoryStream(Convert.FromBase64String(serializedItems));
245 
246             SessionStateItemCollection sessionItems =
247               new SessionStateItemCollection();
248 
249             if (ms.Length > 0)
250             {
251                 BinaryReader reader = new BinaryReader(ms);
252                 sessionItems = SessionStateItemCollection.Deserialize(reader);
253             }
254 
255             return new SessionStateStoreData(sessionItems,
256               SessionStateUtility.GetSessionStaticObjects(context),
257               timeout);
258         }
259 
260 
261     }
262 
263 
264     [Serializable]
265     public class CustomSession
266     {
267 
268         public string SessionId
269         {
270             get;
271             set;
272         }
273 
274         public string ApplicationName
275         {
276             get;
277             set;
278         }
279         public DateTime Created
280         {
281             get;
282             set;
283         }
284         public DateTime Expires
285         {
286             get;
287             set;
288         }
289         public DateTime LockDate
290         {
291             get;
292             set;
293         }
294         public int LockId
295         {
296             get;
297             set;
298         }
299         public int Timeout
300         {
301             get;
302             set;
303         }
304         public bool Locked
305         {
306             get;
307             set;
308         }
309         public string SessionItems
310         {
311             get;
312             set;
313         }
314         public int Flags
315         {
316             get;
317             set;
318         }
319 
320 
321     }
322 }

 

 

三 、 使用  


protected void Button1_Click(object sender, EventArgs e)
{

   Session["jinshuai"] = "你好:" + DateTime.Now.ToString();


}

protected void Button2_Click(object sender, EventArgs e)
{
    this.Label1.Text = (Session["jinshuai"]?? "没找到值").ToString();
}

 

附:

https://msdn.microsoft.com/zh-cn/library/system.web.sessionstate.sessionstatestoreproviderbase(VS.80).aspx

 

ASP.NET 会话状态使用会话状态存储提供程序将会话数据写入数据存储区,并从中读取会话数据。会话状态存储提供程序是一个类,它继承SessionStateStoreProviderBase 抽象类并使用特定于数据存储区的实现重写其成员。在处理 ASP.NET 页的过程中,SessionStateModule 类会调用会话状态存储提供程序以便与数据存储区进行通信,从而存储和检索会话变量和相关的会话信息,如超时值。

对于每个 SessionID 属性,每个 ASP.NET 应用程序内的会话数据都将单独存储。ASP.NET 应用程序不共享会话数据。

如本主题中的示例所示,可以为 ASP.NET 应用程序指定一个自定义 SessionStateStoreProviderBase 实现,方法是将 sessionState 配置元素的mode 属性设置为 Custom,并将 customProvider 属性设置为自定义提供程序的名称。

锁定会话存储区数据

由于 ASP.NET 应用程序是多线程的,支持对并发请求的响应,因此并发请求可能会尝试访问同一会话信息。考虑下面一种情况,其中一个框架集中的多个框架都访问同一应用程序。框架集内每个框架的单独请求可能会在 Web 服务器中的不同线程上并发执行。如果每个框架源代码的 ASP.NET 页都访问会话状态变量,则可能会出现多个线程并发访问会话存储区。

为避免在会话存储区发生数据冲突以及意外的会话状态行为,SessionStateModule 和 SessionStateStoreProviderBase 类包含了锁定功能,可以在 ASP.NET 页执行期间,以独占方式为特定的会话锁定会话存储项。请注意,即使 EnableSessionState 属性标记为 ReadOnly,同一应用程序中的其他 ASP.NET 页也可以向会话存储区写入,因此对于存储区中只读会话数据的请求可能最终仍将等待锁定数据的释放。

在调用 GetItemExclusive 方法的过程中,在请求开始时就会对会话存储区数据设置锁定。请求完成后,在调用 SetAndReleaseItemExclusive 方法期间释放锁定。

如果 SessionStateModule 对象在调用 GetItemExclusive 或 GetItem 方法期间遇到锁定的会话数据,它将以半秒为间隔重新请求会话数据,直到锁定被释放或者会话数据的锁定时间超过 ExecutionTimeout 属性的值。如果超过了执行超时时间,SessionStateModule 对象将调用ReleaseItemExclusive 方法以释放会话存储区数据并随即请求会话存储区数据。

在针对当前的响应调用 SetAndReleaseItemExclusive 方法前,由于锁定的会话存储区数据可能已经通过调用单独线程上的ReleaseItemExclusive 方法而释放,因此可能会尝试设置和释放已被另一会话释放并修改的会话状态存储区数据。为了避免这种情况,GetItem 和GetItemExclusive 方法返回一个锁定标识符。此锁定标识符必须包含在每个请求中以修改锁定的会话存储区数据。仅当数据存储区中的锁定标识符与 SessionStateModule 提供的锁定标识符匹配时,才能修改会话存储区数据。

删除过期的会话存储区数据

当针对特定的会话调用 Abandon 方法时,将使用 RemoveItem 方法从数据存储区中删除该会话的数据;否则,数据将保留在会话数据存储区供会话的以后请求使用。由 SessionStateStoreProviderBase 实现来删除过期的会话数据。

 

目录
相关文章
|
6月前
|
存储 缓存 安全
Django的会话框架提供了一种简单且安全的方式来在用户与网站之间存储和检索状态信息
【5月更文挑战第12天】Django的会话管理依赖于内置的SessionMiddleware。要启用,需在settings.py的MIDDLEWARE中包含它,并确保&#39;django.contrib.sessions&#39;在INSTALLED_APPS内。设置SESSION_ENGINE可选择存储引擎,如默认的数据库或缓存。在视图中,通过request.session交互会话数据。模板可以直接访问这些数据。配置包括会话超时、cookie属性和存储后端。注意,敏感数据不宜存入会话,确保会话cookie安全,考虑使用缓存降低数据库压力。
62 3
|
6月前
客户端禁用cookie后的会话数据保存问题
客户端禁用cookie后的会话数据保存问题
|
安全 数据安全/隐私保护
如何处理多个Yii2.0应用程序之间的SSO会话共享?
如何处理多个Yii2.0应用程序之间的SSO会话共享?
|
Go 数据库 数据安全/隐私保护
第四十章 构建数据库应用程序 - 绑定到属性
第四十章 构建数据库应用程序 - 绑定到属性
97 0
|
关系型数据库 数据库连接 数据库
Confluence 6 在数据源连接中启用校验查询
确定 Confluence 在数据库连接池中校验数据库连接: 停止 Confluence。 编辑 /conf/server.xml 文件(或者基于在那里你配置你的数据源)。
814 0