Session丢失问题

最近在开发一ASP.NET2.0系统时,在程序中做删除或创建文件操作时,出现session丢失问题。在网上搜了不少资料,最后终于解决了,采用了如下方法:
1、 asp.net Session 的实现
asp.net的Session是基于HttpModule技术做的,HttpModule可以在请求被处理之前,对请求进行状态控制,由于Session本身就是用来做状态维护的,因此用HttpModule做Session是再合适不过了。
ASP.NET 提供了 Session 对象,从而允许程序员识别、存储和处理同一个浏览器对象对服务器上某个特定网络应用程序的若干次请求的上下文信息。 Session 对应浏览器与服务器的同一次对话,在浏览器第一请求网络应用程序的某个页面时,服务器会触发 Session_onStart 事件;在对话超时或者被关闭的时候会触发 Session_onEnd 事件。 程序员可以在代码中响应这两个事件来处理与同一次对话相关的任务,如开辟和释放该次对话要使用的资源等。
   ASP.NET 的程序中要使用 Session 对象时,必须确保页面的 @page 指令中 EnableSessionState 属性是 True 或者 Readonly ,并且在 web.config 文件中正确的设置了 SessionState 属性。
  ASP.NET Session 的状态保持是由 web.config 文件中的 <system.web> 标记下的 <sessionstate> 标记的 mode 属性来决定的。该属性有四种可能的值: Off Inproc StateServer SQlServer.
  设为 Off 会禁用 Session.
  Inproc 是缺省的设置 , 这种模式和以前的 ASP 的会话状态 的方法是类似的 , 会话的状态会被保存在 ASP.NET 进程中,它的优点是显而易见的:性能。进程内的数据访问自然会比夸进程的访问快。 然而,这种方法 Session 的状态依赖于 ASP.NET 进程,当 IIS 进程崩溃或者正常重起启时,保存在进程中的状态将丢失。
  为了克服 Inproc 模式的缺点, ASP.NET 提供了两种进程外保持会话状态的方法。
  ASP.NET 首先提供了提供了一个 Windows 服务: ASPState , 这个服务启动后, ASP.NET 应用程序可以将 mode 属性设置为 “SateServer”, 来使用这个 Windows 服务提供的状态管理方法。
  除了在 web.config 文件中设置 mode 属性为 StateServer 外,还必须设置运行 StateServer 服务器的 IP 地址和端口号 . 如果 IIS 所在的机器运行 StateServer IP 地址就是 127.0.0.1, 端口号通常是 42424. 配置如下:
 mode=”StateServer”
 stateConnectionString="tcpip=127.0.0.1:42424"
    使用这种模式 , 会话状态的存储将不依赖 IIS 进程的失败或者重启 , 会话的状态将存储在 StateServer 进程的内存空间中。
   另一种会话状态模式是 SQLServer 模式。这种模式是将会话的状态保存在 SQL Server 数据库中的。使用这种模式前,必须至少有一台 SQL Server 服务器,并在服务器中建立需要的表和存储过程。 .NET SDK 提供了两个脚本来简化这个工作: InstallSqlState.sql UnInstallSqlState.sql 。这两国文件存放在下面路径中:
  <%SYSTEMDRIVER%>/Winnt/Microsoft.NET/Framework/<%version%>/
要配置 SQL Server 服务器,可以在命令行中运行 SQL Server 提供的命令行工具 osql.exe
  osql -s [server name] -u [user] -p [password] <InstallSqlState.sql
例如:
  osql -s (local) -u as -p “”-i  InstallSqlState.sql
做好必要的数据库准备工作后,将 web.config 文件中的 sessionstate 元素的 mode 属性改为 ”sqlserver”, 并指定 SQL 连接字符串。具体如下:
  mode="SQLServer"
    sqlConnectionString="data source=127.0.0.1;userid=sa;password=;Trusted_Connection=yes"
使用 SQLServer 模式处了可以使 Session 的状态不依赖于 IIS 服务器之外,还可以利用 SQL Server 的集群,使状态存储不依赖于单个的 SQL Server, 这样就可以为应用程序提供极大的可靠性。
 
2、 丢失原因:
转( 1 ): Asp.net 默认配置下, Session 莫名丢失的原因及解决办法
      正常操作情况下 Session 会无故丢失。因为程序是在不停的被操作,排除 Session 超时的可能。另外, Session 超时时间被设定成 60 分钟,不会这么快就超时的。
     
这次到 CSDN 上搜了一下帖子,发现好多人在讨论这个问题,然后我又 google 了一下,发现微软网站上也有类似的内容。
现在我就把原因和解决办法写出来。
原因:
由于 Asp.net 程序是默认配置,所以 Web.Config 文件中关于 Session 的设定如下:
<sessionState
mode = 'InProc'
stateConnectionString = 'tcpip=127.0.0.1:42424'
sqlConnectionString = 'data source=127.0.0.1;Trusted_Connection=yes'
cookieless = 'true'
timeout = '60' />

我们会发现 sessionState 标签中有个属性 mode ,它可以有 3 种取值: InProc StateServer?SQLServer (大小写敏感) 。默认情况下是 InProc ,也就是将 Session 保存在进程内( IIS5 aspnet_wp.exe ,而 IIS6 W3wp.exe ),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的 Session 丢失。
[ asp Session 是具有进程依赖性的。 ASP Session 状态存于 IIS 的进程中,也就是 inetinfo.exe 这个程序。所以当 inetinfo.exe 进程崩溃时,这些信息也就丢失。 ]

哪些情况下该进程会重起呢?微软的 一篇文章 告诉了我们:
1 、配置文件中 processModel 标签的 memoryLimit 属性
2
Global.asax 或者 Web.config 文件被更改
3
Bin 文件夹中的 Web 程序( DLL )被修改
4
、杀毒软件扫描了一些 .config 文件。
更多的信息请参考 PRB: Session variables are lost intermittently in ASP.NET applications
解决办法:
      前面说到的 sessionState 标签中 mode 属性可以有三个取值,除了 InProc 之外,还可以为 StateServer SQLServer 。这两种存 Session 的方法都是进程外的,所以当 aspnet_wp.exe 重起的时候,不会影响到 Session

     
现在请将 mode 设定为 StateServer StateServer 是本机的一个服务 ,可以在系统服务里看到服务名为 ASP.NET State Service 的服务,默认情况是不启动的。当我们设定 mode StateServer 之后,请手工将该服务启动。 这样,我们就能利用本机的 StateService 来存储 Session 了,除非电脑重启或者 StateService 崩掉,否则 Session 是不会丢的(因 Session 超时被丢弃是正常的)。
     
除此之外,我们还可以 Session 通过其他电脑的 StateService 来保存 [ 如使用状态服务器 ] 。具体的修改是这样的。同样还在 sessionState 标签中,有个 stateConnectionString='tcpip=127.0.0.1:42424' 属性,其中有个 ip 地址,默认为本机( 127.0.0.1 ),你可以将其改成你所知的运行了 StateService 服务的电脑 IP ,这样就可以实现位于不同电脑上的 Asp.net 程序互通 Session 了。

     
如果你有更高的要求,需要在服务期重启时 Session 也不丢失,可以考虑将 mode 设定成 SQLServer ,同样需要修改 sqlConnectionString 属性。关于使用 SQLServer 保存 Session 的操作,请访问 这里
     
在使用 StateServer 或者 SQLServer 存储 Session 时,所有需要保存到 Session 的对象除了基本数据类型(默认的数据类型,如 int string 等)外,都必须序列化。 只需将 [Serializable] 标签放到要序列化的类前就可以了。
如:
[Serializable]
public class MyClass
{
    ......
}
具体的序列化相关的知识请参 这里
至此,问题解决。
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值