Session是互联网应用中非常重要的玩意儿,对于超过单台部署的站点集群,都会存在会话共享的需求。在web.config中,微软提供了sessionstate节点来定义不同的Session状态存储方式。本文就自定义模式下的Session状态存储驱动提供一些干货。
首先,想要接管Session状态存储,需要了解一些基本的东西。
SessionIDManager
/// <summary> /// 自定义SessionID管理器 /// </summary> public class CustomSessionIDManager : SessionIDManager { /// <summary> /// 创建SessionID /// </summary> /// <param name="context"></param> /// <returns></returns> public override string CreateSessionID(HttpContext context) { return string.Format("{0}.{1}", SessionPRoviderConfigurationSectionHandler.SessionProviderSettings.SessionProfix, base.CreateSessionID(context)); } /// <summary> /// 验证 /// </summary> /// <param name="id"></param> /// <returns></returns> public override bool Validate(string id) { string prefix = string.Empty; string realId = string.Empty; if (string.IsNullOrEmpty(id) || id.Trim().Length == 0) { return false; } var parsedValues = id.Split('.'); if (parsedValues == null || parsedValues.Length != 2) { return false; } prefix = parsedValues[0]; realId = parsedValues[1]; return base.Validate(realId); } }
想要共享Session,肯定就会有SessionID的前缀需求,而SessionIDManager就提供了可自定义的虚方法,这边以CustomSessionIDManager举例。CreateSessionID方法提供了创建SessionID的实现,重载该方法,用{0}.{1}的方式提供基于前缀的SessionID生成。而Validate是拆解带前缀的SessionID来验证真实的SessionID。
SessionStateStoreProviderBase
/// <summary> /// 自定义Session状态存储驱动 /// </summary> public sealed class CustomSessionStateStoreProvider : SessionStateStoreProviderBase { /// <summary> /// 构造函数 /// </summary> public CustomSessionStateStoreProvider() { sessionStateStoreBehavior = SessionProviderBehaviorFactory.CreateSessionStateStoreBehaviorInstance(); } /// <summary> /// Session状态存储行为 /// </summary> readonly ISessionStateStoreBehavior sessionStateStoreBehavior; /// <summary> /// 创建新的存储数据 /// </summary> /// <param name="context"></param> /// <param name="timeout"></param> /// <returns></returns> public override SessionStateStoreData CreateNewStoreData(System.Web.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(System.Web.HttpContext context, string id, int timeout) { sessionStateStoreBehavior.CreateUninitializedItem(context, id, timeout); } /// <summary> /// 获取项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actions"></param> /// <returns></returns> public override SessionStateStoreData GetItem(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return sessionStateStoreBehavior.GetItem(false, context, id, out locked, out lockAge, out lockId, out actions); } /// <summary> /// 独占获取项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actions"></param> /// <returns></returns> public override SessionStateStoreData GetItemExclusive(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return sessionStateStoreBehavior.GetItem(true, context, id, out locked, out lockAge, out lockId, out actions); } /// <summary> /// 独占释放项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="lockId"></param> public override void ReleaseItemExclusive(System.Web.HttpContext context, string id, object lockId) { sessionStateStoreBehavior.ReleaseItem(context, id, lockId); } /// <summary> /// 移除项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="lockId"></param> /// <param name="item"></param> public override void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item) { sessionStateStoreBehavior.RemoveItem(context, id, lockId); } /// <summary> /// 重设项的超时时间 /// </summary> /// <param name="context"></param> /// <param name="id"></param> public override void ResetItemTimeout(System.Web.HttpContext context, string id) { sessionStateStoreBehavior.ResetItemTimeout(context, id); } /// <summary> /// 独占设置并释放项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="item"></param> /// <param name="lockId"></param> /// <param name="newItem"></param> public override void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { sessionStateStoreBehavior.SetAndReleaseItem(context, id, item, lockId, newItem); } /// <summary> /// 回收 /// </summary> public override void Dispose() { } /// <summary> /// 结束请求 /// </summary> /// <param name="context"></param> public override void EndRequest(System.Web.HttpContext context) { } /// <summary> /// 初始化请求 /// </summary> /// <param name="context"></param> public override void InitializeRequest(System.Web.HttpContext context) { } /// <summary> /// 设置项过期回掉 /// </summary> /// <param name="expireCallback"></param> /// <returns></returns> public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) { return false; } }
SessionStateStoreProviderBase是提供Session状态存储驱动的基类。从基类分析,想要灵活扩展,核心就是对Session存储的那些方法实现进行抽象,让驱动在执行方法的时候不关心实现由谁来提供。因此,写一个SessionStateStoreBehavior接口,在CustomSessionStateStoreProvider的构造函数中,通过工厂在运行时得到实例。
SessionStateStoreBehavior
/// <summary> /// Session状态存储行为接口 /// </summary> public interface ISessionStateStoreBehavior { /// <summary> /// 创建未初始化的项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="timeout"></param> void CreateUninitializedItem(System.Web.HttpContext context, string id, int t
新闻热点
疑难解答