在 Asp.net Mvc 自定義Session (一) 中咱們把數據緩存工具類寫好了,今天在咱們在這篇把 剩下的自定義Session寫完html
首先還請你們跟着個人思路一步步的來實現,既然咱們要自定義Session確定要繼承和重寫什麼東東(由於在框架設計中確定考慮這些東西,asp.net mvc 架構師不傻的),好吧 確實要繼承 SessionStateStoreProviderBase 這個基類。下面我先把代碼貼出來,在慢慢解釋緩存
/// <summary> /// 分佈式session /// </summary> public class ClusterSessionStoreProvider : SessionStateStoreProviderBase { private CacheManager _Client = CacheManager.Instance; private static readonly int _DefaultSessionExpireMinute = 20; private int _timeout; /// <summary> /// 構造函數 /// </summary> public ClusterSessionStoreProvider() { } /// <summary> /// 請求初始化的時候 /// </summary> /// <param name="context"></param> public override void InitializeRequest(HttpContext context) { } public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) { // string applicationVirtualPath = AppDomain.CurrentDomain.BaseDirectory; if (string.IsNullOrWhiteSpace(config["timeout"])) { this._timeout = _DefaultSessionExpireMinute; } else { this._timeout = Convert.ToInt32(config["timeout"]); } } public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) { return new SessionStateStoreData(new SessionStateItemCollection() , SessionStateUtility.GetSessionStaticObjects(context), timeout); } /// <summary> ///將新的會話狀態添加到數據區中 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="timeout"></param> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { SessionDataObject sessionObject = new SessionDataObject { Content = null, Locked = false, SetTime = DateTime.Now, LockId = 0, ActionFlag = 1 }; _Client.Put(id, sessionObject, timeout); } public override void Dispose() { //調用dispose 須要的操做 } public override void EndRequest(HttpContext context) { //請求結束時調用 } public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { SessionStateStoreData sessionStateStoreDate = null; SessionDataObject memcachedSessionObject = null; DateTime setTime = DateTime.Now; lockAge = TimeSpan.Zero; lockId = null; locked = false; actions = SessionStateActions.None; memcachedSessionObject = _Client.Get(id) as SessionDataObject; if (memcachedSessionObject != null) { //若是已經鎖定 if (memcachedSessionObject.Locked) { lockAge = memcachedSessionObject.LockAge; lockId = memcachedSessionObject.LockId; locked = memcachedSessionObject.Locked; actions = (SessionStateActions)memcachedSessionObject.ActionFlag; return sessionStateStoreDate; } memcachedSessionObject.LockId++; memcachedSessionObject.SetTime = setTime; _Client.Put(id, memcachedSessionObject); actions = (SessionStateActions)memcachedSessionObject.ActionFlag; lockId = memcachedSessionObject.LockId; lockAge = memcachedSessionObject.LockAge; if (actions == SessionStateActions.InitializeItem) { sessionStateStoreDate = this.CreateNewStoreData(context, _timeout); } else { sessionStateStoreDate = this.Deserialize(context, memcachedSessionObject.Content, _timeout); } return sessionStateStoreDate; } return sessionStateStoreDate; } //從緩衝區中讀取只讀屬性 public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return GetItem(context, id, out locked, out lockAge, out lockId, out actions); } //釋放鎖定 public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { SessionDataObject memcachedSessionObject = _Client.Get(id) as SessionDataObject; if (memcachedSessionObject != null) { memcachedSessionObject.Locked = false; memcachedSessionObject.LockId = (Int32)lockId; _Client.Put(id, memcachedSessionObject, _timeout); } } //刪除緩存數據 public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { _Client.Delete(id); } public override void ResetItemTimeout(HttpContext context, string id) { object obj = _Client.Get(id); if (obj != null) { _Client.Put(id, obj, _timeout); } } //更新值 public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { DateTime setTime = DateTime.Now; byte[] bytes = this.Serialize((SessionStateItemCollection)item.Items); SessionDataObject memcachedSessionObject = new SessionDataObject() { LockId = 0, Locked = false, Content = bytes, ActionFlag = 0, SetTime = setTime }; _Client.Put(id, memcachedSessionObject, item.Timeout); } public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) { return false; } private SessionStateStoreData Deserialize(HttpContext context, byte[] bytes, int timeout) { MemoryStream stream = new MemoryStream(bytes); SessionStateItemCollection collection = new SessionStateItemCollection(); if (stream.Length > 0) { BinaryReader reader = new BinaryReader(stream); collection = SessionStateItemCollection.Deserialize(reader); } return new SessionStateStoreData(collection, SessionStateUtility.GetSessionStaticObjects(context), timeout); } private byte[] Serialize(SessionStateItemCollection items) { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); if (items != null) items.Serialize(writer); writer.Close(); return ms.ToArray(); } }
這個類的代碼以下:session
[Serializable] public class SessionDataObject { public byte[] Content { get; set; } public bool Locked { get; set; } public DateTime SetTime { get; set; } public int LockId { get; set; } public int ActionFlag { get; set; } public TimeSpan LockAge { get; set; } }
2. 增刪改查都要重寫,如 GetItemExclusive 重寫這個方法時,每次獲取session(如:session['test'])都會調用這個方法,你根據sessionId往 緩存工具類中讀取返回就行架構
3. 重寫完了指定方法後,要在配置文件中加上,才能使用mvc
/************************************************ * * <sessionState mode="Custom" customProvider="SessionProvider" > <providers> <add name="SessionProvider" type="NanHuaDDD.ClusterSession.ClusterSessionStoreProvider,NanHuaDDD" timeout="1" accessKey="你好" /> </providers> * * ******************************************************************/
到這裏 我就不一 一列出每一個方法的意思了,差很少你們一看方法名就知道,分佈式用的是memcache,若是在後面系統升級,要求集羣是否是很方便啊app
若是有什麼疑問能夠聯繫我 QQ:209229923框架