Session 共享(Custom模式)By Memcached(原创)

1、web.config配置:

<machineKey decryptionKey="FD69B2EB9A11E3063518F1932E314E4AA1577BF0B824F369" validationKey="5F32295C31223A362286DD5777916FCD0FD2A8EF882783FD3E29AB1FCDFE931F8FA45A8E468B7A40269E50A748778CBB8DB2262D44A86BBCEA96DCA46CBC05C3" validation="SHA1" decryption="Auto"/>
 <sessionState mode="Custom" customProvider="SessionProvider" timeout="120">
		  <providers>
			  <add name="SessionProvider" type="Entity.MemcachedSessionProvider, Entity" />
		  </providers>
	  </sessionState>
	  
    <httpModules>
		<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		<add name="CrossDomainCookieModule" type="Entity.SessionProviderHttpModule, Entity"/>
	</httpModules>

2、Entity.MemcachedSessionProvider 代码

public class MemcachedSessionProvider : SessionStateStoreProviderBase
    {
        private IMemcacheBiz _Client;
        private static readonly int _DefaultSessionExpireMinute = 20;
        private int _timeout;

        public MemcachedSessionProvider()
        {
            _Client = new MemcacheBiz();
        }

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            string applicationVirtualPath = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
            Configuration webconfig = WebConfigurationManager.OpenWebConfiguration(applicationVirtualPath);
            SessionStateSection _objConfig = (SessionStateSection)webconfig.GetSection("system.web/sessionState");

            if (_objConfig == null || _objConfig.Timeout == null || _objConfig.Timeout.Minutes <= 0)
            {
                this._timeout = _DefaultSessionExpireMinute;
            }
            else
            {
                this._timeout = _objConfig.Timeout.Minutes;
            }
        }

        public override void InitializeRequest(HttpContext context)
        {
            //throw new NotImplementedException();
        }

        public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
        {
            return new SessionStateStoreData(new SessionStateItemCollection(),
                SessionStateUtility.GetSessionStaticObjects(context), timeout);
        }

        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            MemcachedSessionObject sessionObject
                = new MemcachedSessionObject
                {
                    Content = null,
                    Locked = false,
                    SetTime = DateTime.Now,
                    LockId = 0,
                    ActionFlag = 1
                };
            _Client.Set(id, sessionObject, TimeSpan.FromMinutes(timeout));
        }

        public override void Dispose()
        {
            //throw new NotImplementedException();
        }

        public override void EndRequest(HttpContext context)
        {
            //throw new NotImplementedException();
        }

        public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked,
            out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
        {
            SessionStateStoreData sessionStateStoreData = null;
            MemcachedSessionObject memcachedSessionObject = null;
            DateTime setTime = DateTime.Now;

            lockAge = TimeSpan.Zero;
            lockId = null;
            locked = false;
            actions = SessionStateActions.None;
            memcachedSessionObject = _Client.Get(id) as MemcachedSessionObject;

            if (memcachedSessionObject != null)
            {
                //如果已经锁定
                if (memcachedSessionObject.Locked)
                {
                    lockAge = memcachedSessionObject.LockAge;
                    lockId = memcachedSessionObject.LockId;
                    locked = memcachedSessionObject.Locked;
                    actions = (SessionStateActions)memcachedSessionObject.ActionFlag;
                    return sessionStateStoreData;
                }

                memcachedSessionObject.LockId++;
                memcachedSessionObject.SetTime = setTime;

                _Client.Set(id, memcachedSessionObject);

                actions = (SessionStateActions)memcachedSessionObject.ActionFlag;
                lockId = memcachedSessionObject.LockId;
                lockAge = memcachedSessionObject.LockAge;

                if (actions == SessionStateActions.InitializeItem)
                    sessionStateStoreData = this.CreateNewStoreData(context, _timeout);
                else
                    sessionStateStoreData = this.Deserialize(context, memcachedSessionObject.Content, _timeout);

                return sessionStateStoreData;
            }

            return sessionStateStoreData;
        }

        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)
        {
            MemcachedSessionObject memcachedSessionObject = _Client.Get(id) as MemcachedSessionObject;
            if (memcachedSessionObject != null)
            {
                memcachedSessionObject.Locked = false;
                memcachedSessionObject.LockId = (Int32)lockId;
                _Client.Set(id, memcachedSessionObject, TimeSpan.FromMinutes(_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.Set(id, obj, TimeSpan.FromMinutes(_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);
            MemcachedSessionObject memcachedSessionObject = new MemcachedSessionObject
            {
                LockId = 0,
                Locked = false,
                Content = bytes,
                ActionFlag = 0,
                SetTime = setTime
            };
            _Client.Set(id, memcachedSessionObject, TimeSpan.FromMinutes(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();
        }
    }

这里面涉到一些memcache的方法,在下一节有说明

原文地址:https://www.cnblogs.com/ruiati/p/3270539.html