Asp.net Mvc 自定義Session (二)

  在 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();
        }




    }

  


  1.   在代碼中有一個SessionDataObject類,這個類是存儲Session的一些基本信息,以保證訪問時還能取得上次設置的值(這個類必定要序列還 否則嘻嘻。。)

   這個類的代碼以下: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框架

相關文章
相關標籤/搜索