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的方法,在下一节有说明