多个.NET项目中共享session

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengkang511/article/details/79808775

随着项目的发展,把一个庞大项目的各个模块进行拆分分离应该是必须经历的阶段,如果一个项目的会员中心、m站、APP数据接口都在一起,为了降低各个模块之间的影响,项目的分离更有必要。

最近要做的就是对项目进行拆分,由于之前是用session记录的用户状态,比如很常用的一个 Session["userid"],所以面临的第一件事就是session的共享,准备采取的方案是session的状态服务,即StateServer模式,状态服务是一个独立的进程,可以跟项目分开放在不同的服务器上,灵活性还是很高的,下面是具体配置:

1、计算机的管理=》服务=》ASP.NET 状态服务,启动类型设置为“自动”,并启动

2、在运行处输入regedit,进入注册表,进入“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\aspnet_state\Parameters”,修改“AllowRemoteConnection”的值为1(表示允许远程连接),“Port”表示的是状态服务的端口号,默认是42424,也可以自定义

3、在webconfig的<system.web>内部添加一行

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

其中192.168.1.6是状态服务器的IP地址,42424是端口号,需要session共享的项目都要添加。

网上90%的资料中都是这样说明的,但是根本行不通,虽然这样配置之后不同的项目的ASP.NET_SessionId是一样的,但是但是读取不到设置的值。。。

最后从分布式中使用Redis实现Session共享(二)这篇博客中找到解决方法,还有最后一步,需要在Global中再添加上这一段

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);
            FieldInfo configMode = typeof(SessionStateModule).GetField("s_configMode", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);

            SessionStateMode mode = (SessionStateMode)configMode.GetValue(ssm);
            if (mode == SessionStateMode.StateServer)
            {
                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);
                        object obj = null;
                        uribaseInfo.GetValue(obj);
                    }
                }
            }
            break;
        }
    }
}

注意,上述代码需要在每个项目中添加,appname可以自定义,但要在各项目中要保持一致,另外不同项目的主域名需要是一致的,如“a.spzs.com”、“b.spzs.com”的主域名都是“spzs.com”。

本人亲测在2.0和4.0不同版本的项目中Session可以共享,最后吐槽下只管复制粘贴发博客,不验证、不求证的行为。

猜你喜欢

转载自blog.csdn.net/fengkang511/article/details/79808775
今日推荐