Asp.net 实现Session分布式储存(Redis,Mongodb,Mysql等) sessionState Custom
1/// <summary>2 /// 自定义Session实现方式
3 /// </summary>
4 public>
5 {
6 /// <summary>
7 /// 获取配置文件的设置的默认超时时间
8 /// </summary>
9 private static TimeSpan _expiresTime;
10
11 /// <summary>
12 /// 获取Web.config 在sessionState设置的超时时间
13 /// </summary>
14 static MyCustomSessionStateStoreProvider()
15 {
16 System.Web.Configuration.SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)System.Configuration.ConfigurationManager.GetSection("system.web/sessionState");
17 _expiresTime = sessionStateSection.Timeout;
18 }
19
20 /// <summary>
21 /// 创建新的存储数据
22 /// </summary>
23 /// <param name="context"></param>
24 /// <param name="timeout"></param>
25 /// <returns></returns>
26 public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
27 {
28 return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
29 }
30
31 /// <summary>
32 /// 创建未初始化的项,就是初始化Session数据
33 /// </summary>
34 /// <param name="context"></param>
35 /// <param name="id"></param>
36 /// <param name="timeout"></param>
37 public override void CreateUninitializedItem(HttpContext context, string>
38 {
39 using (SessionStateEF db = new SessionStateEF())
40 {
41 var session = new ASPStateTempSessions
42 {
43 Created = DateTime.Now,
44 Expires = DateTime.Now.AddMinutes(timeout),
45 Flags = (int)SessionStateActions.InitializeItem,
46 LockDate = DateTime.Now,
47 Locked = false,
48 SessionId =>
49 LockId = 0,
50 Timeout = timeout
51 };
52 db.ASPStateTempSessions.Add(session);
53 db.SaveChanges();
54 }
55 }
56
57 /// <summary>
58 /// 释放锁定的项,就是把锁定的Session的锁的状态清除掉
59 /// </summary>
60 /// <param name="context"></param>
61 /// <param name="id"></param>
62 /// <param name="lockId"></param>
63 public override void>
64 {
65 using (SessionStateEF db = new SessionStateEF())
66 {
67 var session = db.ASPStateTempSessions.Find(id);
68 if (session == null)
69 {
70 return;
71 }
72
73 // 把locked设置为false
74 session.Locked = false;
75 session.Expires = DateTime.Now + _expiresTime;
76 db.SaveChanges();
77 }
78
79 }
80
81 /// <summary>
82 /// 删除Session,会在Session.Abandon()的时候调用
83 /// </summary>
84 /// <param name="context"></param>
85 /// <param name="id"></param>
86 /// <param name="lockId"></param>
87 /// <param name="item"></param>
88 public override void RemoveItem(HttpContext context, string>
89 {
90 using (SessionStateEF db = new SessionStateEF())
91 {
92 var session = db.ASPStateTempSessions.Find(id);
93 if (session == null)
94 {
95 return;
96 }
97
98 db.ASPStateTempSessions.Remove(session);
99 db.SaveChanges();
100 }
101 }
102
103 /// <summary>
104 /// 设置超时时间
105 /// </summary>
106 /// <param name="context"></param>
107 /// <param name="id"></param>
108 public override void ResetItemTimeout(HttpContext context, string>
109 {
110 using (SessionStateEF db = new SessionStateEF())
111 {
112 var session = db.ASPStateTempSessions.Find(id);
113 if (session == null)
114 {
115 return;
116 }
117 session.Expires = DateTime.Now + _expiresTime;
118 db.SaveChanges();
119 }
120 }
121
122 /// <summary>
123 /// 新建或者释放锁定的项并设置Session的值
124 /// </summary>
125 /// <param name="context"></param>
126 /// <param name="id"></param>
127 /// <param name="item"></param>
128 /// <param name="lockId"></param>
129 /// <param name="newItem"></param>
130 public override void SetAndReleaseItemExclusive(HttpContext context, string>
131 {
132 using (SessionStateEF db = new SessionStateEF())
133 {
134 // 判断是否是新建,如果是新建则和CreateUninitializedItem不同在于Timeout和有初始值。
135 if (newItem)
136 {
137 var session = new ASPStateTempSessions
138 {
139 Created = DateTime.Now,
140 Expires = DateTime.Now.AddMinutes(item.Timeout),
141 Flags = (int)SessionStateActions.None,
142 LockDate = DateTime.Now,
143 Locked = false,
144 SessionId =>
145 LockId = 0,
146 Timeout = item.Timeout,
147 SessionItem = Serialize((SessionStateItemCollection)item.Items)
148 };
149 db.ASPStateTempSessions.Add(session);
150 db.SaveChanges();
151 }
152 else// 释放锁定的项并设置Session的值
153 {
154 var session = db.ASPStateTempSessions.FirstOrDefault(i => i.SessionId ==>
155 if (session == null)
156 {
157 return;
158 }
159
160 session.Expires = DateTime.Now.AddMinutes(item.Timeout);
161 session.Locked = false;
162 session.LockId = Convert.ToInt32(lockId);
163 session.SessionItem = Serialize((SessionStateItemCollection)item.Items);
164 db.SaveChanges();
165 }
166 }
167 }
168
169 /// <summary>
170 /// 获取项,这个方式主要是把Session状态设置为只读状态时调用。
171 /// </summary>
172 /// <param name="context"></param>
173 /// <param name="id"></param>
174 /// <param name="locked"></param>
175 /// <param name="lockAge"></param>
176 /// <param name="lockId"></param>
177 /// <param name="actions"></param>
178 /// <returns></returns>
179 public override SessionStateStoreData GetItem(HttpContext context, string>
180 {
181 return DoGet(false, context,>
182 }
183
184 /// <summary>
185 /// 独占获取项,除了Session状态为只读时调用
186 /// </summary>
187 /// <param name="context"></param>
188 /// <param name="id"></param>
189 /// <param name="locked"></param>
190 /// <param name="lockAge"></param>
191 /// <param name="lockId"></param>
192 /// <param name="actions"></param>
193 /// <returns></returns>
194 public override SessionStateStoreData GetItemExclusive(HttpContext context, string>
195 {
196 return DoGet(true, context,>
197 }
198
199 /// <summary>
200 /// 获取Session的值
201 /// </summary>
202 /// <param name="isExclusive"></param>
203 /// <param name="context"></param>
204 /// <param name="id"></param>
205 /// <param name="locked"></param>
206 /// <param name="lockAge"></param>
207 /// <param name="lockId"></param>
208 /// <param name="actions"></param>
209 /// <returns></returns>
210 public SessionStateStoreData DoGet(bool isExclusive, HttpContext context, string>
211 {
212 using (SessionStateEF db = new SessionStateEF())
213 {
214 // 设置初始值
215 var item = default(SessionStateStoreData);
216 lockAge = TimeSpan.Zero;
217 lockId = null;
218 locked = false;
219 actions = 0;
220
221 // 如果数据存储区中未找到任何会话项数据,则GetItemExclusive 方法将 locked 输出参数设置为false,并返回 null。
222 // 这将导致 SessionStateModule调用 CreateNewStoreData 方法来为请求创建一个新的SessionStateStoreData 对象。
223 var session = db.ASPStateTempSessions.Find(id);
224 if (session == null)
225 {
226 return null;
227 }
228
229 // 判断session是否是ReadOnly 模式,不是readonly模式得判断是否锁住
230 if (isExclusive)
231 {
232 // 如果在数据存储区中找到会话项数据但该数据已锁定,则GetItemExclusive 方法将 locked 输出参数设置为true,
233 // 将 lockAge 输出参数设置为当前日期和时间与该项锁定日期和时间的差,将 lockId 输出参数设置为从数据存储区中检索的锁定标识符,并返回 nul
234 if (session.Locked)
235 {
236 locked = true;
237 lockAge = session.LockDate - DateTime.Now;
238 lockId = session.LockId;
239 return null;
240 }
241 }
242
243 // 判断是否过期
244 if (session.Expires < DateTime.Now)
245 {
246 db.ASPStateTempSessions.Remove(session);
247 return null;
248 }
249
250 // 处理值
251 lockId = lockId == null ? 0 : (int)lockId + 1;
252 session.Flags = (int)SessionStateActions.None;
253 session.LockId = Convert.ToInt32(lockId);
254
255 // 获取timeout
256 var timeout = actions == SessionStateActions.InitializeItem ? _expiresTime.TotalMinutes : session.Timeout;
257
258 // 获取SessionStateItemCollection
259 SessionStateItemCollection sessionStateItemCollection = null;
260
261 // 获取Session的值
262 if (actions == SessionStateActions.None && !string.IsNullOrEmpty(session.SessionItem))
263 {
264 sessionStateItemCollection = Deserialize((session.SessionItem));
265 }
266
267 item = new SessionStateStoreData(sessionStateItemCollection ?? new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), (int)timeout);
268
269 return item;
270
271 }
272
273 }
274
275
276 #region 序列化反序列化Session的值
277 /// <summary>
278 /// 反序列化Session的数据
279 /// </summary>
280 /// <param name="item"></param>
281 /// <returns></returns>
282 public SessionStateItemCollection Deserialize(string item)
283 {
284 MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(item));
285 SessionStateItemCollection collection = new SessionStateItemCollection();
286 if (stream.Length > 0)
287 {
288 BinaryReader reader = new BinaryReader(stream);
289 collection = SessionStateItemCollection.Deserialize(reader);
290 }
291 return collection;
292 }
293
294 /// <summary>
295 /// 序列化Session的数据
296 /// </summary>
297 /// <param name="items"></param>
298 /// <returns></returns>
299 public string Serialize(SessionStateItemCollection items)
300 {
301 MemoryStream ms = new MemoryStream();
302 BinaryWriter writer = new BinaryWriter(ms);
303 if (items != null)
304 items.Serialize(writer);
305 writer.Close();
306 return System.Text.Encoding.ASCII.GetString(ms.ToArray());
307 }
308
309 #endregion
310
311
312 public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
313 {
314 return true;
315 }
316 public override void InitializeRequest(HttpContext context)
317 {
318 }
319 public override void EndRequest(HttpContext context)
320 {
321 }
322 public override void Dispose()
323 {
324 }
325
326 }
页:
[1]