Session跨域、Session共享、Mode=StateSever方式解决问题

时间:2023-03-10 00:48:58
Session跨域、Session共享、Mode=StateSever方式解决问题

前言

很多童鞋在工作或面试的过程中,也许会遇到这样的问题,使用Session,怎样让多个站点实现Session共享的问题,也就是在A站点登录,那么在B站点就不需要重新登录了那?如果采用Session保存用户信息的话,那么应该怎样解决那?

解决方式之一:使用StateSever

一:sessionState中Mode 的常见三种用法

1. InProc:通常情况下我们都采用这个方法,他表示session值保存在IIS进程中

优点:访问速度快

缺点:易丢失(IIs崩溃、应该程序池超时、重启等都会引起)

2. StateServer:net专门保存Session的一个进程服务中

优点:相对稳定,不易丢失

缺点:访问速度稍慢,毕竟他的值是保存在另外一个进程中。

3. SQLServer:保存在数据中

优点:稳定

缺点:速度慢

二:下面我们就采用第二种方式StateServer解决Session共享问题,使用方法及注意事项如下:

1.将计算机服务"ASP.NET State Service"启动类型改为自动,同时启动改服务。

2.打开注册表,运行cmd/regedit,找到节点HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspnet_state\Parameters

  a.将AllowRemoteConnection值设置为1

  [b.将Port值设置为a5b8(十六进制),即十进制42424(默认值)]

  以上根据字面意思就可以看出允许远程连接和设置端口

3.分别在A网站和B网站的配置文件WebConfig 中system.web节点下添加

<sessionState mode="StateServer" stateConnectionString="tcpip=192.168.1.1:42424" timeout="60"></sessionState>

  注意:如果不操作步骤2 或 AllowRemoteConnection=0 那么所有的站点只能在本机  且 stateConnectionString中IP地址必须配置为 localhost:42424或127.0.0.1:42424

4.分别在网站项目A和网站项目B的Global.asax.cs中加入下面代码

        public override void Init()
{
base.Init();
foreach (string moduleName in this.Modules)
{
string appName = "AppName";
IHttpModule module = this.Modules[moduleName];
SessionStateModule ssm = module as SessionStateModule;
if (ssm != null)
{
FieldInfo storeInfo = typeof(SessionStateModule).GetField("_store",
BindingFlags.Instance |
BindingFlags.NonPublic);
SessionStateStoreProviderBase store = (SessionStateStoreProviderBase)storeInfo.GetValue(ssm);
if (store == null) //In IIS7 Integrated mode, module.Init() is called later
{
FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime",
BindingFlags.Static |
BindingFlags.NonPublic);
HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId",
BindingFlags.Instance |
BindingFlags.NonPublic);
appNameInfo.SetValue(theRuntime, appName);
}
else
{
Type storeType = store.GetType();
if (storeType.Name.Equals("OutOfProcSessionStateStore"))
{
FieldInfo uribaseInfo = storeType.GetField("s_uribase",
BindingFlags.Static | BindingFlags.NonPublic);
uribaseInfo.SetValue(storeType, appName);
}
}
}
}
}

注意两个AppName必须设置为一样,为了让浏览器知道这是一个程序。

以上就是解决Session共享的全部内容,有什么问题,欢迎大家指正。