保存在Session里的自定义类型如下: 进程内Session运行正常,stateSever,跟SqlServer Session运行总会出现如下错误, 寻思了一阵子还是解决不了,目前打算自己实现个简单的Session,于是就开始了解asp.net Session的实现方式 Session机制的基本描述 Http是无状态的,Asp.net 会在用户访问具体.aspx页面时写个Asp.net_SessionId:xxxxxxxxxxx的cookie到客户端的浏览器中(也可以通过url方式),这样客户浏览器以后发起的每个请求都会带上这个cookie数据(可以通过火狐的fireBug中的网络观察到),asp.net利用从Asp.net_SessionId字段中获取的数据,也就是"xxxxxxxxxxx"到Session数据存储区(InProc,SqlServer,StateServer)检索对应的数据,然后构造出Session相关对象,供客户程序访问,具体一点的说就是通过SessionStateModule注册HttpApplication生命周期中的AcquireRequestState与ReleaseRequestState事件,分别将数据存储区的数据读出反序列化后附加到访问HttContext.Session上,以及将HttContext.Session数据序列化后保存到数据存储区中,而对数据存储区的读写由实现了SessionStateStoreProviderBase的类完成(Asp.net的提供程序模型)。 涉及的主要类 Session工作的基本流程 注意:这个流程图我参考相关资料大致画的,打算自己按这个方式实现一个MySession,不是微软Session的完整流程,MS的那个代码涉及面太多了,本人水平有限没完整理清。 上图中有个IRequiresSessionState类型是一个标记接口,用来告诉SessionStateModule是否要给当前请求构建立Session对象,一般站点上对.jpg,.png.html等资源的请求是不会发给asp.net来处理的,但是如果你配置了IIS,或者采用MVC建立应用程序时,对这些资源的请求都会发给asp.net的,如果跟踪请求会发现有大量图片的页面在打开时会有大量的ResetTimout操作出现,影响性能,这个时候可以将具体的资源目录(如/images)转化成虚拟目录,并取消静态资源到asp.net处理程序的映射 Session的锁定机制 Session数据是一个浏览器一份的(默认采用Httponley cookie来保存SessionId)数据间各自独立,但是如果网站中使用框架,或ajax中并行发起请求,就可能出现Session访问并发问题,Asp.net采用的机制是针对两个并发的请求(携带同一个SessionID),asp.net会根据SessionID去锁定Session数据存储中的对应记录,直到HttpAplication的ReleaseRequestState阶段释放锁定,而这个时候另外一个并非请求会被阻塞,并且每隔半秒再尝试一次直到超时或锁定成功。 Asp.net程序中,一个请求会由一个HttpApplication类应答,一个HttpApplication同一时间只处理一个请求,但是会有多个HttpApplication存在,以提供对网站并发访问请求的处理,HttpApplication是可以重复利用的,每个HttpApplication中都有一组独立的HttpModule,HttpApplication对象在被第一次创建时会根据配置建立自己的HttpMoudle集合,并调用每个HttpModule的Init方法,而每个HttpApplication再次被使用时(除创建那次外),不会再次构建HttpModule集合,当然也不会调用注册的HttpModule的Init方法了,这点在实现SessionStateModule时需要注意,内存结构参考下图: Session的序列化 Session中的数据采用BinaryWriter,BinaryReader进行读写,具体在声明成internal的System.Web.Util.AltSerialization中实现, |