Session共享的解决方案

1、客户端SessionID值唯一;

      对于不同的域名:主域名、子域名、跨站点域名或跨服务器域名,用户在打开页面时会产生不同的SessionID,

为了使这些站点在用户登录时只登录一次,那我们就要解决SessionID的问题,必须使SessionID在这些共享Session的站点中只产生一次。而SessionID是存储在客户端的cookie之中键值为ASP.NET_SessionId的一个字符串(也可以存储在URL中,这里不作使介绍),为此只须使各站点存储的SP.NET_SessionId唯一即可。

      因每个客户端在打开时会产生一个SessionID,为此我们要做的就是重置SessionID。我们可以在继承HttpModule,在结束请求时重写SessionID。

 


Session共享的解决方案_.NETSession共享的解决方案_.NET_02代码如下

public class MakeSessionIDOneOnly : IHttpModule
{
private string m_RootDomain = string.Empty;


#region IHttpModule Members


public void Dispose()
{


}


public void Init(HttpApplication context)
{
m_RootDomain = ConfigurationManager.AppSettings["RootDomain"];


Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore");
FieldInfo uriField = stateServerSessionProvider.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);


if (uriField == null)
throw new ArgumentException("UriField was not found");


uriField.SetValue(null, m_RootDomain);


context.EndRequest += new System.EventHandler(context_EndRequest);
}


void context_EndRequest(object sender, System.EventArgs e)
{
HttpApplication app = sender as HttpApplication;
for (int i = 0; i < app.Context.Response.Cookies.Count; i++)
{
if (app.Context.Response.Cookies[i].Name == "ASP.NET_SessionId")
{
app.Context.Response.Cookies[i].Domain = m_RootDomain;
}
}
}


#endregion
}


  

为使用以上代码,须配置下面节点项。

     <httpModules>

             <add name="节点名称" type="类名全称, 程序集"/>

     </httpModules>

 

2、Session值的共享;

配置sessionState置节点,使用StateServer或SQLServer来实现Session共享。

为实现跨服务器共享,必须在Web.config配置:

<machineKey decryptionKey="FD69B2EB9A11E3063518F1932E314E4AA1577BF0B824F369" validationKey="5F32295C31223A362286DD5777916FCD0FD2A8EF882783FD3E29AB1FCDFE931F8FA45A8E468B7A40269E50A748778CBB8DB2262D44A86BBCEA96DCA46CBC05C3" validation="SHA1" decryption="Auto"/>

并且,不同服务器上站点配置必须用相同的Web.config,各站点目录配置也要相同。

 

2.1、使用StateServer:

存储Session的服务器必须开启StateServer:ASP.NET状态服务。只有机器重起的情况下才导致Session丢失。

<sessionState cookieless="false" timeout="50" mode="StateServer" stateConnectionString="tcpip=IpAddress:42424"/>

     若StateServer在本机存储,则IpAddress为:127.0.0.1;若StateServer为远程服务器,则为IpAddress为远程服务器IP地址,并且修改注册表项如下:

Windows Registry Editor Version 5.00

 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters]

"Port"=dword:0000a5b8

"AllowRemoteConnection"=dword:00000001

       

2.2、使用SQLServer:

必须开启SQLServer代理服务,此服务负责清除过期的Session,若没有开服务,则Session不会过期。

使用SQLServer在机器重启后Session不会丢失。       

Web.config配置:

<sessionState mode="SQLServer" sqlConnectionString="server=DBIpAddress; uid=myid; pwd=mypwd;"/>

 

数据库配置:

使用aspnet_regsql.exe工具

ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库.该工具位于 Web 服务器上的"系统根目录\Microsoft.NET\Framework\版本号"文件夹中.

使用举例:

aspnet_regsql.exe -S . -U sa -P 123456 -ssadd -sstype p

-S参数:

表示数据库实例名称. 可以用"."表示本机.

-U和-P参数:

表示用户名和密码.

-E参数:

可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.

-ssadd / –ssremove 参数:

-ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.

sstype 参数说明:


t



将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。



p



将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。



c



将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。


 

sessionState参数说明:

 

作者:xinhaijulan​

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。