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节点下添加

1
<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中加入下面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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共享的全部内容,有什么问题,欢迎大家指正。

posted on   码农弟  阅读(439)  评论(0编辑  收藏  举报

努力加载评论中...
点击右上角即可分享
微信分享提示