ASP.NET Session的共享

注:

在ashx文件中使用Session

首先添加引用

using System.Web.SessionState;

实现接口

public class XXXX: IHttpHandler
==>
public class XXXX: IHttpHandler, IRequiresSessionState

使用的时候需要通过HttpContext对象调用,如

public void ProcessRequest (HttpContext hc) {
    string code = hc.Session["Cold"].ToString();
}

 

为了实现负载均衡,Session的共享是必须要面对的事情

同一个用户,先后发出的多次请求很可能不是同一台服务器处理的, 那么默认的进程中 Session存储方式 在这多次的处理中就无法共享Session。

解决这个问题,要有两个事情要面对:

  • Session在服务器端是以字典的形式存储的,而获取Session的键就是Cookie(ASP.NET_SessionId),每个服务器都会创建一个SessionId来与客户端的保持联系,所以如何让多个服务器使用同一个SessionId是一个问题。
  • 原来Session是存到每个服务器的对应进程中的,现在要共享Session,就需要在统一的地点存储这些内容。

 

解决方案:

第一个问题,处理方法就是每个服务器都设置Cookie(ASP.NET_SessionId)的Domain,这样多个服务器就可以使用同一个SessionId了。

注:请求到达后台,如果没有发现同域下的SessionId,则会重新生成一个SessionId,并覆盖到客户端的Cookies中。

using System;
using System.Configuration;
using System.Reflection;
using System.Web;
using System.Web.SessionState;

namespace Entity
{
    public class SessionProviderHttpModule : 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
    }
}

然后还要将这个httpModule注入到项目中,即在<system.webServer>或<system.web>的modules中添加一个节点。

  <system.webServer>
    <modules>
      <add name="CrossDomainCookieModule" type="Entity.SessionProviderHttpModule,Entity" />
    </modules>
  </system.webServer>

 

第二个问题的解决方法有多种,如状态服务器、SQL Server、分布式缓存(Memcache)。

具体细节参考另一篇文章 ASP.NET Session的保存


 

原文:http://www.cnblogs.com/lori/p/3723714.html

posted @ 2015-09-23 20:52  TiestoRay  阅读(1021)  评论(0编辑  收藏  举报