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共享的全部内容,有什么问题,欢迎大家指正。

posted on 2017-02-07 17:14  码农弟  阅读(439)  评论(0编辑  收藏  举报