ASP.NET会话(Session)保存模式

 
【原创】 ASP.NET 会话( Session )保存模式
作者 寒羽枫 (cityhunter172)
 
大家好,已有四个多月没写东东啦。今日抽空就说一下 Session .Net v1.0/v1.1 中的存储模式。大家可在 MSDN 2003 中搜索一下 < sessionState > 即可看到关于 Web.config 中的 < sessionState > 节点元素的描述,共有 Off InProc StateServer SQLServer 四种模式。 Off InProc 分别指“不启用”、“进程内保存(默认值)”,此两种模式没啥讲的,所谓 InProc 就是把 Session 保存在 aspnet_wp.exe (Windows 2000 解析 ASP.NET 页面所用的进程 ) w3wp.exe (Win2003 的进程 ) 中,一旦进程被中止或被重置, Session 将丢失。
一、        引发 Session 丢失的几种原因
动过手写代码的人都知道, Session 丢失是比较常见的事。以下是本人这几年所遇到的,能够引发 Session 丢失的原因,不敢说是百分百,丢失概率还是特别高的。错…,简直可以说是“相…当…”高哇 ^_^"
1、    存放 Session 的电脑重启(废话,若这样都不丢,你神仙啊)
2、    模式:aspnet_wp.exew3wp.exe 在“任务管理器”中或其它情况下导致其进程被终止运行。 InProc
3、    模式:修改 .cs 文件后,编译了两次(只编译一次,有时不会丢失) InProc
4、    模式:修改了Web.config InProc
5、    模式,Windows 2003 环境:应用程序池回收、停止后重启 InProc
6、    模式:服务器上 bin 目录里的 .dll 文件被更新 InProc
以上列举的都是 InProc 模式下,容易引发解析 ASP.NET 应用程序重置的原因。是不是觉得很窝火?之前我也有这种感觉,慢慢就习惯啦,再后来就干脆不用这种模式了。于是乎,就有了使用下列两种模式的尝试,现写出来与大家一起分享。
二、        使用 StateServer 保存 Session
StateServer 模式的实质是,把 Session 存放在一个单独的进程里,此进程独立于 aspnet_wp.exe w3wp.exe 。启用此服务后,在“任务管理器”中可以看到一个名为 aspnet_state.exe 的进程,下面开始说明一下设置的具体步骤:
 
1、    修改注册表(关键步骤,如下图)
运行 regedit 打开注册表 找到 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 节点 AllowRemoteConnection 的键值设置成“ 1 ”( 1 为允许, 0 代表禁止)→ 设置 Port ( 端口号 )
注意事项:
       a) 、若 ASP.NET State Service 正在运行,修改注册表内容后,则需要重新启动该服务
b) 、注意端口号的键值是以十六进制储存的,可以使用十进制进行修改, 42424 是默认的端口
c) AllowRemoteConnection 的键值设置成“ 1 后,意味着允许远程电脑的连接,也就是说只要知道你的服务端口,就可享用你的 ASP.NET State Service ,即把 Session 存放在你的电脑进程内,因此请大家慎用;键值为“ 0 时,仅有 stateConnectionString 为“ tcpip=localhost: 42424与“tcpip=127.0.0.1:42424的情况,方可使用 ASP.NET State Service
 ASP.NET会话(Session)保存模式_第1张图片
 
2、    开启 ASP.NET State Service (如下图)
右键点击“我的电脑”→ 管理 服务与应用程序 服务 双击“ ASP.NET State Service 启动(可设为“自动”)
说明:只要安装了 .Net Framework v1.0/v1.1 ,都拥有此服务。
ASP.NET会话(Session)保存模式_第2张图片 
 
3、    更改 Web.config
打开 Web.config 找到 < sessionState > 节点内容
< sessionState
            mode ="InProc"
            stateConnectionString ="tcpip=127.0.0.1:42424"
            sqlConnectionString ="data source=127.0.0.1;Trusted_Connection=yes"
            cookieless ="false"
            timeout ="20" />
 
将其改为以下内容
< sessionState mode ="StateServer"   stateConnectionString ="tcpip=192.168.0.2:42424" timeout ="20" />
注意事项:
       a) 、设成 StateServer 后,必须要有对应的 stateConnectionString
       b) 、注意 IP 地址(可以是远程计算机 IP 、计算机名称、域名)与端口号,端口号需与 ASP.NET State Service 的服务端口一致
 
三、        Session 放入 SQLServer 保存
SQLServer 模式就是,把 Session 存放在 SQL Server 数据库里(注意不是 Oracle ,动动脚趾都能猜到原因啦),下面开始说明一下设置的具体步骤:
 
1、    启动相关的数据库服务(如图)
运行 SQL Server 服务管理器 启动 SQL Server (最好设为开机自动运行) 启动 SQL Server Agent 服务(最好设为开机自动运行)
注意事项:
       a) 、注意启动顺序,也可通过下列方式设置: 右键点击“我的电脑”→ 管理 服务与应用程序 服务 找到“ MSSQLSERVER ”与“ SQLSERVERAGENT 启动并设置启动类型为“自动”
b) SQL Server Agent 在此处的作用是清除数据库中已过期的 Session
  ASP.NET会话(Session)保存模式_第3张图片
ASP.NET会话(Session)保存模式_第4张图片
 
2、    建立存放 Session DataBase
运行“ SQL 查询分析器”→ 使用“ sa ”或是拥有“ master ”的 db_owner 权限的用户登录数据库 打开查询文件 C:/WINNT/Microsoft.NET/Framework/v1.1.4322/InstallSqlState.sql (存放在 Windows 系统目录的 .Net 安装目录下可找到) 直接运行该 sql 脚本 刷新数据库即可看到名为 ASPState DataBase
 ASP.NET会话(Session)保存模式_第5张图片
 ASP.NET会话(Session)保存模式_第6张图片
 
3、    建立连接数据库 ASPState 的用户,并为此用户授权(此步骤可跳过)
进行此步的原因是:一是不想在 Web.config 中出现 sa 的密码;二是 tempdb 在数据库启动后仅保留 sa 一个帐号的使用权限,其余帐号的权限统统被清除,但保存 Session 又需要用到此 DataBase
 
A) 、运行 SQL Server 的企业管理器 展开数据库的安全性 右击“登录” 新建“登录” 输入“名称” 选择 SQL Server 身份验证” 输入“密码” 指定“数据库” 点击“数据库访问” 勾选 ASPState 选中“ db_owner ”角色 点击“确定” 再一次输入“密码” 点击“确定” 后即可建立 ASPState 的用户(此处建立名为“ SessionStateUser ”,密码为“ 123456 的测试用户)
ASP.NET会话(Session)保存模式_第7张图片 
      ASP.NET会话(Session)保存模式_第8张图片ASP.NET会话(Session)保存模式_第9张图片
 ASP.NET会话(Session)保存模式_第10张图片
 
B) 、运行 SQL Server 的企业管理器 展开“管理” 展开“ SQL Server 代理” 右击“作业” 点击“新建作业” 输入 “名称”(此例为 GrantSessionUser 点击标签 “步骤” 新建 输入 “步骤名”(此例为 Grant01 选择数据库“ tempdb 编写 SQL 脚本“ exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner' ”→ 确定 点击标签 “调度” 新建 输入 “名称”(此例为 Start01 )→ 选择类型“ SQL Server 代理启动时自动启动” 确定 最后点击“确定”新增完毕
 ASP.NET会话(Session)保存模式_第11张图片ASP.NET会话(Session)保存模式_第12张图片ASP.NET会话(Session)保存模式_第13张图片ASP.NET会话(Session)保存模式_第14张图片
 
 
 
C )、也可运行以下脚本一次性搞定以上 A B 两个步骤
/****** 脚本开始 ******/
      -- 新建数据库帐号 SessionStateUser ,默认登录 ASPState
EXEC sp_addlogin 'SessionStateUser' , '123456' , 'ASPState'
 
use ASPState         -- 切换 DataBase
 
      -- SessionStateUser 授予 db_owner 的权限
exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner'
 
use master             -- 切换 DataBase
 
BEGIN TRANSACTION   
      /****** 声明变量 ******/         
    DECLARE @JobID BINARY ( 16 )  
    DECLARE @ReturnCode INT    
    SELECT @ReturnCode = 0    
 
    -- 若没有,则添加作业的分类
    IF ( SELECT COUNT (*) FROM msdb.dbo. syscategories WHERE name = N '[Uncategorized (Local)]' ) < 1
        EXECUTE msdb.dbo.sp_add_category @name = N '[Uncategorized (Local)]'
 
    -- 新建作业
    EXECUTE @ReturnCode = msdb.dbo.sp_add_job    -- 调用存储过程 sp_add_job
            @job_id = @JobID OUTPUT ,           -- 将返回的 JobID ,赋值给变量
            @job_name = N 'GrantSessionUser' ,   -- 作业名称
            @owner_login_name = NULL,           -- 默认为当前用户所有
            @description = null,
            @category_name = N '[Uncategorized (Local)]' ,        -- 作业分类归属
            @enabled = 1 ,                    -- 是否启用
            @notify_level_email = 0 ,
            @notify_level_page = 0 ,
            @notify_level_netsend = 0 ,
            @notify_level_eventlog = 0 ,
            @delete_level = 0
 
    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback -- 出错则回滚
   
    -- 新建步骤
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep -- 调用存储过程 sp_add_jobstep
            @job_id = @JobID ,                    -- 传入刚刚新建的 JobID
            @step_id = 1 ,
            @step_name = N 'Grant01' ,         -- 步骤名称
            @command = N 'exec sp_adduser ''SessionStateUser'', ''SessionUser'' ,''db_owner''',
             -- 需要执行的 SQL 脚本(注意用两个连续的单引号表示 SQL 中的单引号)
 
            @database_name = N 'tempdb' , -- 执行上述 SQL 所用的 DataBase
            @server = N '' ,
            @database_user_name = N '' ,
             @subsystem = N 'TSQL' ,    -- 执行类型为“ Transact-SQL 脚本”
            @cmdexec_success_code = 0 ,
            @flags = 0 ,
            @retry_attempts = 0 ,
            @retry_interval = 1 ,
            @output_file_name = N '' ,
            @on_success_step_id = 0 ,
            @on_success_action = 1 ,
            @on_fail_step_id = 0 ,
            @on_fail_action = 2
 
    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback
   
    -- 新建调度
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule
             @job_id = @JobID ,
            @name = N 'Start01' ,   -- 调度名称
            @enabled = 1 ,
            @freq_type = 64               -- 64 表示 SQLServerAgent 服务启动时运行
 
    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback
   
    -- 将新建的作业添加到本地数据库
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID , @server_name = N '(local)'
    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback
   
    COMMIT TRANSACTION          
    GOTO    EndSave              
QuitWithRollback:
    IF ( @@TRANCOUNT > 0 ) ROLLBACK TRANSACTION
EndSave :
/****** 脚本结束 ******/
 
4、    设置 Web.config 内容
打开 Web.config 找到 < sessionState > 节点内容 修改为以下内容即可:
< sessionState mode ="SQLServer"   sqlConnectionString ="data source=192.168.0.2; user id= SessionStateUser; password=123456" timeout ="20" />
注意事项:
       a) sqlConnectionString 中不能出现 initial catalog 选项
b) SQL Server Agent 在此处的作用是清除数据库中已过期的 Session
c )、你若跳过了第三步,则 user id 需要用 sa 进行登录
d )、若 sqlConnectionString data source=127.0.0.1;Trusted_Connection=yes ”,则使用本地计算机 ASPNET Windows 2000 系统帐户)或 Network Service Windows 2003 系统帐户)的身份登录数据库。要是数据库不允许上述用户登录,则报错;同样,即使上述帐户能成功登录,也要分配其 tempdb 的权限,理由是 Session 是保存在 tempdb 中的,若没有该 DataBase 的存取权限是行不滴。见下图:
 ASP.NET会话(Session)保存模式_第15张图片
 
寒羽枫( cityhunter172
2006-05-14 00:01 完稿  
 
 

你可能感兴趣的:(ASP.NET会话(Session)保存模式)