建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

当前位置: 建站学 > 网站开发 > asp.net教程 >

ASP.NET中纠结的Session备忘(2)

时间:2011-05-11 16:42来源: 作者: 点击:
保存在Session里的自定义类型如下: 进程内Session运行正常,stateSever,跟SqlServer Session运行总会出现如下错误, 寻思了一阵子还是解决不了,目前打算自己实现个简单的Session,于是就开始了解asp.net Session的

保存在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中实现,
Session数据最终按: [数据类型编号1][数据长度][数据][数据类型编号2][数据]...这样的方式存在成二进制格式,需要注意的是当[数据类型编号]是int,long这些长度已知的数据类型时[数据长度]是不写入的,另外自定义类型由BinaryFormatter类对流进行读写,代码截图如下:

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片