自定義會話狀態存儲提供程序

自定義會話狀態存儲提供程序web

 

 此版本程序只是說明  自定義會話  能夠放在不一樣的地方, 能夠改形成 把會話分佈式存儲 等。服務器

 

1、Web.config session

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

 

2、 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();ide


}this

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

 

附:

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 實現來刪除過時的會話數據。

相關文章
相關標籤/搜索