|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
|
vkFLinux联盟 vkFLinux联盟 从实现角度来看,上节中提到的 SessionStateModule.InitModuleFromConfig 函数,根据配置文件中状态管理器的模式,分别建立 System.Web.SessionState.InProcStateClientManager, System.Web.SessionState.OutOfProcStateClientManager 和 System.Web.SessionState.SqlStateClientManager 三类状态管理器的实例。他们都继承自 System.Web.SessionState.StateClientManager 抽象基类,并通过 System.Web.SessionState.IStateClientManager 接口向 HttpApplication 提高状态管理服务。 vkFLinux联盟 vkFLinux联盟 IStateClientManager 接口是状态管理器的统一管理接口,主要提供以下功能: vkFLinux联盟 internal interface System.Web.SessionState.IStateClientManager.IStateClientManager vkFLinux联盟 { vkFLinux联盟 // 配置管理状态管理器 vkFLinux联盟 void ConfigInit(SessionStateSectionHandler.Config config, SessionOnEndTarget onEndTarget); vkFLinux联盟 // 保存 SessionStateModule 实例供后面使用 vkFLinux联盟 void SetStateModule(SessionStateModule module); vkFLinux联盟 void ResetTimeout(string id); vkFLinux联盟 void Dispose(); vkFLinux联盟 vkFLinux联盟 void Set(string id, SessionStateItem item, bool inStorage); vkFLinux联盟 vkFLinux联盟 // 维护状态管理器内容 vkFLinux联盟 IAsyncResult BeginGet(string id, AsyncCallback cb, object state); vkFLinux联盟 SessionStateItem EndGet(IAsyncResult ar); vkFLinux联盟 vkFLinux联盟 IAsyncResult BeginGetExclusive(string id, AsyncCallback cb, object state); vkFLinux联盟 SessionStateItem EndGetExclusive(IAsyncResult ar); vkFLinux联盟 void ReleaseExclusive(string id, int lockCookie); vkFLinux联盟 } vkFLinux联盟 ConfigInit 方法主要在初始化状态管理器时通知其根据配置进行初始化工作,并将负责会话状态清除的 SessionOnEndTarget 对象实例绑定到会话管理器(我们后面讨论会话状态管理实现时详细讨论)。对 OutOfProcStateClientManager 和 SqlStateClientManager 来说,在此阶段还会初始化与外部服务器的连接,并通过一个 System.Web.Util.ResourcePool 实例,提供基于时间策略的资源池来维护连接; vkFLinux联盟 ResetTimeout 方法重置指定 Session 的超时时间;对 InProcStateClientManager 来说,这个超时时间是通过 System.Web.Caching.CacheInternal 类型实现的缓存对象来使用的; OutOfProcStateClientManager 直接通过 MakeRequest 函数构造请求发给外部独立的状态管理器执行; SqlStateClientManager 则调用存储过程 TempResetTimeout 更新 ASPStateTempSessions 表的过期时间 Expires 字段; vkFLinux联盟 Dispose 方法是否状态管理器的资源,落实到代码就是对 OutOfProcStateClientManager 和 SqlStateClientManager 中资源池的释放; vkFLinux联盟 vkFLinux联盟 Set 方法则将指定的 SessionStateItem 存储到 id 相关的会话数据中,并根据 inStorage 指定的对象状态,决定在发生异常的情况下是否释放对此会话的锁。与 ResetTimeout 的实现类似,OutOfProcStateClientManager 发送请求给外部独立的状态管理器;SqlStateClientManager 调用存储过程 TempUpdateStateItemXXX 更新会话状态表 ASPStateTempSessions 中的过期时间 Expires 字段、锁定状态 Lock 字段、以及状态信息 SessionItemShort/SessionItemLong (分别保存7000字节以下或之上的数据)。如发生异常并设置 inStorage 标记,则先调用 TempReleaseStateItemExclusive 释放会话锁。 vkFLinux联盟 vkFLinux联盟 对状态管理器中数据的获取较为复杂,IStateClientManager 接口使用的是异步调用的模式,并为提高效率将独占的获取数据单独拿出来。状态管理器实现类通过通用基类 System.Web.SessionState.StateClientManager 实现的几个工具方法,将数据获取操作异步化。再最终由实现类通过 Get 和 GetExclusive 方法完成操作。获取数据的方法 InProcStateClientManager 通过缓存;OutOfProcStateClientManager 通过请求;SqlStateClientManager 通过 TempGetStateItemXXX 存储过程完成。 vkFLinux联盟 vkFLinux联盟 在了解了 SessionStateModule 控制的状态服务器的实现和使用方法后,我们来看看上层的 HttpSessionState 是如何使用的。 vkFLinux联盟
HttpSessionState 的 Item 属性实际上是通过 SessionDictionary 实例实现的。 vkFLinux联盟 public sealed class HttpSessionState : vkFLinux联盟 { vkFLinux联盟 private SessionDictionary _dict; vkFLinux联盟 vkFLinux联盟 public object this[string name] vkFLinux联盟 { vkFLinux联盟 get vkFLinux联盟 { vkFLinux联盟 return _dict[name]; vkFLinux联盟 } vkFLinux联盟 set vkFLinux联盟 { vkFLinux联盟 _dict[name] = value; vkFLinux联盟 } vkFLinux联盟 } vkFLinux联盟 } vkFLinux联盟 vkFLinux联盟 vkFLinux联盟 而此 SessionDictionary 实例与 HttpSessionState 实例的构造,都是在前面提到的完成会话构造的 SessionStateModule.CompleteAcquireState 方法中完成的: vkFLinux联盟 vkFLinux联盟 public sealed class SessionStateModule : IHttpModule vkFLinux联盟 { vkFLinux联盟 private string _rqId; vkFLinux联盟 private SessionDictionary _rqDict; vkFLinux联盟 private HttpStaticObjectsCollection _rqStaticObjects; // 静态对象,通过页面中 <object Runat="Server" Scope="Session"/> 标记设置 vkFLinux联盟 private int _rqTimeout; vkFLinux联盟 private bool _rqIsNewSession; vkFLinux联盟 private bool _rqReadonly; vkFLinux联盟 private HttpContext _rqContext; vkFLinux联盟 private SessionStateItem _rqItem; vkFLinux联盟 vkFLinux联盟 private void CompleteAcquireState() vkFLinux联盟 { vkFLinux联盟 if (_rqItem != null) vkFLinux联盟 { vkFLinux联盟 if (_rqItem.dict != null) vkFLinux联盟 { vkFLinux联盟 _rqDict = _rqItem.dict; vkFLinux联盟 } vkFLinux联盟 else vkFLinux联盟 { vkFLinux联盟 _rqDict = new SessionDictionary(); vkFLinux联盟 } vkFLinux联盟 _rqStaticObjects = ((_rqItem.staticObjects != null) ? _rqItem.staticObjects : vkFLinux联盟 _rqContext.Application.SessionStaticObjects.Clone()); vkFLinux联盟 _rqTimeout = _rqItem.timeout; vkFLinux联盟 _rqIsNewSession = false; vkFLinux联盟 _rqInStorage = true; vkFLinux联盟 _rqStreamLength = _rqItem.streamLength; vkFLinux联盟 } vkFLinux联盟 else vkFLinux联盟 { vkFLinux联盟 _rqDict = new SessionDictionary(); vkFLinux联盟 _rqStaticObjects = _rqContext.Application.SessionStaticObjects.Clone(); vkFLinux联盟 _rqTimeout = SessionStateModule.s_config._timeout; vkFLinux联盟 _rqIsNewSession = true; vkFLinux联盟 _rqInStorage = false; vkFLinux联盟 } vkFLinux联盟 _rqDict.Dirty = false; vkFLinux联盟 vkFLinux联盟 _rqSessionState = new HttpSessionState(_rqId, _rqDict, _rqStaticObjects, _rqTimeout, _rqIsNewSession, vkFLinux联盟 SessionStateModule.s_config._isCookieless, SessionStateModule.s_config._mode, _rqReadonly); vkFLinux联盟 vkFLinux联盟 _rqContext.Items.Add("AspSession", _rqSessionState); vkFLinux联盟 vkFLinux联盟 } vkFLinux联盟 } vkFLinux联盟 vkFLinux联盟 vkFLinux联盟 这儿涉及到的几个字段,基本上都能跟 HttpSessionState 提供的公共属性对应起来。需要注意的是 HttpSessionState.StaticObjects 是通过 ASP.NET 页面上的 <object Runat="Server" Scope="Session"/> 类似标记静态定义的;_rqReadonly 则是前面提到的 <%@ Page EnableSessionState=" ReadOnly" %> 标记设置的。 vkFLinux联盟 至此,状态管理器的使用与实现方法基本上分析完成,下面整理一下其使用流程: vkFLinux联盟 vkFLinux联盟 1.构造:HttpApplication 在初始化过程中调用 InitModules 初始化配置文件 Machine.config 中注册的实现了 IHttpModule 接口的 HTTP 模块;其中 SessionStateModule 作为模块之一被构造并初始化;其 InitModuleFromConfig 方法根据配置文件中状态管理器的相关配置,构造并初始化相应的状态管理器;并根据各种条件调用 CompleteAcquireState 方法完成 HttpSessionState 的构造工作。 vkFLinux联盟 2.使用:HttpSessionState 通过 SessionDictionary 实现其 Item 属性的状态数据管理;SessionDictionary 本身由 SessionStateModule.OnReleaseState 在适当的时候写回状态管理器;其他维护操作也是通过 SessionStateModule 调用状态管理器的 IStateClientManager 接口完成的。 vkFLinux联盟 3.实现:状态管理器从抽象基类 StateClientManager 获得异步调用的封装;通过 IStateClientManager 接口提供给 SessionStateModule 管理其初始化、释放和管理的接口。 vkFLinux联盟 vkFLinux联盟 虽然 ASP.NET 做了很多工作,但个人感觉还远远不够。例如 InProc/OutOfProc 实际上都是在内存中,只是解决了一个可靠性和数据集中同步的问题;SQL Server 虽然能够解决容量、可靠性和数据集中同步的问题,但效率又受到影响。这方面 .NET 应该向 Java 好好学习一下,例如 Java 下 EHCache 和 OSCache 都提供了平滑的可配置二级(内存/硬盘)缓存介质切换,并且后者还提供了对负载均衡的简单支持,此外还有 JBoss 等实现的基于 IP 多播等实现技术的负载均衡缓存实现等等,都远远超出了 ASP.NET 提供的缓存机制所考虑到的范围。虽然 ASP.NET 也有独立的缓存机制,MS 也提出了 Cache Application Block 的参考实现,不过还是任重而道远啊,呵呵 vkFLinux联盟 vkFLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|
|
|
|
|