跨站点共享Session解决方案、单点登录解决方案(ASP.NET 2.0版本)

我们在进行Web开发时经常会用到Session,用它去标识不同的会话,那么涉及到跨站点的时候如何实现Session共享呢?

通常的解决方案有:使用数据库、使用Cookies做中间桥等等。

下面介绍一种基于ASP.NET 2.0的,通过序列化和反序列化机制实现的一种解决方案。

首先看一下通常的服务器集群的网络拓扑结构:

 

利用序列化机制实现Session共享的原理:

1、Web Server 1的应用程序序列化Session信息为文本值(可以是Binary或Soap格式)

2、将序列化后的值写入文件,保存到File Server上

3、Web Server 2 对保存在File Server上的Session序列化后的值进行反序列化

4、在Web Server 2上重新构建Session值

下面我们来详细看看实现代码,分以下几个步骤:

1、创建一个类库工程:ShareSession

 引入以下的命名空间:

 System.configuration  System.Runtime.Serialization.Formatters.Soap  System.Web

2、创建一个类:SessionEntity

代码如下:

using  System; using  System.Collections.Generic; using  System.Text; using  System.Collections; namespace  ShareSession {     /* *****************************      *       *  Author      :    Xiaojun Liu      *  Create Date :    2007.11.09      *  Description :      *       * *****************************     */     [Serializable]     public class SessionEntity     {                      [NonSerialized]         public string AUTH_GUID = "";         private Hashtable _HtShareSession;         public Hashtable HtShareSession         {             get             {                 return this._HtShareSession;             }             set             {                 this._HtShareSession = value;             }         }         public SessionEntity(string guid)         {             this.AUTH_GUID = guid;         }              }// } //

 

3、创建一个序列化、反序列化操作的类:ShareSessionFormatter

代码如下:

using  System; using  System.Web; using  System.Data; using  System.Collections.Generic; using  System.Text; using  System.Runtime.Serialization.Formatters.Soap; using  System.Runtime.Serialization.Formatters.Binary; using  System.Collections; using  System.IO; namespace  ShareSession {     /**/     /**/     public class ShareSessionFormatter     {         private static string _ShareSessionPath = System.Configuration.ConfigurationManager.AppSettings["ShareSessionPath"].ToString();                  /// <summary>         /// 序列化格式器类型         /// </summary>         public enum FormatterType         {             Binary,             Soap         };         /// <summary>         /// 执行序列化         /// </summary>         /// <param name="formatterType">类型</param>         public static void Serialize(FormatterType formatterType)         {             if (HttpContext.Current.Session["AUTH_GUID"== null)             {                 HttpContext.Current.Session["AUTH_GUID"= Guid.NewGuid().ToString();             }             Hashtable ht = new Hashtable();             //遍历Session                        foreach (string key in HttpContext.Current.Session.Contents.Keys)             {                 ht.Add(key, HttpContext.Current.Session[key]);             }                             ////执行序列化             switch (formatterType)             {                 case FormatterType.Binary:                     BinarySerialize(ht);                     break;                 case FormatterType.Soap:                     SoapSerialize(ht);                     break;                 default:                     break;             }         }         /// <summary>         /// 按照Binary格式序列化         /// </summary>         /// <param name="ht"></param>         private static void BinarySerialize(Hashtable ht)         {             string guid = HttpContext.Current.Session["AUTH_GUID"].ToString();             SessionEntity obj = new SessionEntity(guid);             obj.HtShareSession = ht;                         // 创建一个文件guid.xml             Stream stream = File.Open(_ShareSessionPath + guid + ".xml", FileMode.Create);             BinaryFormatter formatter = new BinaryFormatter();             //执行序列化             formatter.Serialize(stream, obj);             stream.Close();             // 将对象置空             obj = null;         }         /// <summary>         /// 按照Soap格式序列化         /// </summary>         /// <param name="ht"></param>         private static void SoapSerialize(Hashtable ht)         {             string guid = HttpContext.Current.Session["AUTH_GUID"].ToString();             SessionEntity obj = new SessionEntity(guid);             obj.HtShareSession = ht;             // 创建一个文件guid.xml             Stream stream = File.Open(_ShareSessionPath + guid + ".xml", FileMode.Create);             SoapFormatter formatter = new SoapFormatter();             //执行序列化             formatter.Serialize(stream, obj);             stream.Close();             // 将对象置空             obj = null;         }         /// <summary>         /// 反序列化         /// </summary>         /// <param name="formatterType">传送端的Session["AUTH_GUID"]</param>         /// <param name="guid"></param>         public static void Deserialize(FormatterType formatterType, string guid)         {             switch (formatterType)             {                 case FormatterType.Binary:                     BinaryDeserialize(guid);                     break;                 case FormatterType.Soap:                     SoapDeserialize(guid);                     break;                 default:                     break;             }         }         /// <summary>         /// 以Binary方式反序列化         /// </summary>         private static void BinaryDeserialize(string guid)         {             SessionEntity obj = new SessionEntity(guid);             // 打开文件guid.xml             Stream stream = File.Open(_ShareSessionPath + guid + ".xml", FileMode.Open);             BinaryFormatter formatter = new BinaryFormatter();             obj = (SessionEntity)formatter.Deserialize(stream);             stream.Close();             Hashtable ht = obj.HtShareSession;             obj = null;             //遍历ht,生成Session             CreateSession(ht);         }         /// <summary>         /// 以Soap方式反序列化         /// </summary>         private static void SoapDeserialize(string guid)         {             SessionEntity obj = new SessionEntity(guid);             // 打开文件guid.xml             Stream stream = File.Open(_ShareSessionPath + guid + ".xml", FileMode.Open);             SoapFormatter formatter = new SoapFormatter();             obj = (SessionEntity)formatter.Deserialize(stream);             stream.Close();             Hashtable ht = obj.HtShareSession;             obj = null;             //遍历ht,生成Session             CreateSession(ht);         }         /// <summary>         /// 遍历Hashtable,同时创建Session         /// </summary>         /// <param name="ht"></param>         private static void CreateSession(Hashtable ht)         {             foreach (DictionaryEntry de in ht)             {                 HttpContext.Current.Session[de.Key.ToString()] = de.Value;             }         }                       }// } //

 

4、编译项目,生成ShareSession.dll

5、把ShareSession.dll引入Web Server 1上的应用程序中,同时在Web.config文件中增加配置字节

 代码如下:

<!--  Session信息序列化后保存路径  -->          < add  key ="ShareSessionPath"  value ="C:/ShareSession/" />

 

6、在Web Server 1上的应用程序中新建一个页面,功能是初始化Session,然后把Session信息序列化,代码如下:

前台代码:

<% @ Page Language="C#" AutoEventWireup="true" CodeFile="ShareSession.aspx.cs" Inherits="Front_Test_ShareSession"  %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > < html  xmlns ="http://www.w3.org/1999/xhtml" > < head  runat ="server" >      < title > Session共享 </ title > </ head > < body >      < form  id ="form1"  runat ="server" >          < div >              < asp:Label  ID ="lHttp_Cookie"  runat ="server"  Text ="" ></ asp:Label >              < href ="http://localhost:5000/Front/Test/ShareSession.aspx?AUTH_GUID=<%=AUTH_GUID %>" > Go Other Web Site(port:5000) </ a >          </ div >      </ form > </ body > </ html >

后台代码:

using  System; using  System.Data; using  System.Configuration; using  System.Collections; using  System.Web; using  System.Web.Security; using  System.Web.UI; using  System.Web.UI.WebControls; using  System.Web.UI.WebControls.WebParts; using  System.Web.UI.HtmlControls; public   partial   class  Front_Test_ShareSession : System.Web.UI.Page {     public string AUTH_GUID = "";     protected void Page_Load(object sender, EventArgs e)     {         Session.Clear();         Session.Abandon();         Session.Add("USER_ID""2002");         Session.Add("USER_NAME""Xiaojun Liu");         ShareSession.ShareSessionFormatter.Serialize(ShareSession.ShareSessionFormatter.FormatterType.Soap);         AUTH_GUID = Session["AUTH_GUID"].ToString();              } }

 

7、在Web Server 2上进行第5步操作

8、在Web Server 2上的应用程序中新建一个页面,功能是反序列化,还原Session,同时读取Session信息进行测试,代码如下:

前台代码:

<% @ Page Language="C#" AutoEventWireup="true" CodeFile="ShareSession.aspx.cs" Inherits="Front_Test_ShareSession"  %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > < html  xmlns ="http://www.w3.org/1999/xhtml" > < head  runat ="server" >      < title > Session共享 </ title > </ head > < body >      < form  id ="form1"  runat ="server" >          < div >              < asp:Label  ID ="lHttp_Cookie"  runat ="server"  Text ="" ></ asp:Label >          </ div >      </ form > </ body > </ html >

后台代码:

using  System; using  System.Data; using  System.Configuration; using  System.Collections; using  System.Web; using  System.Web.Security; using  System.Web.UI; using  System.Web.UI.WebControls; using  System.Web.UI.WebControls.WebParts; using  System.Web.UI.HtmlControls; public   partial   class  Front_Test_ShareSession : System.Web.UI.Page {     protected void Page_Load(object sender, EventArgs e)     {         string guid = Request.Params["AUTH_GUID"].ToString();         ShareSession.ShareSessionFormatter.Deserialize(ShareSession.ShareSessionFormatter.FormatterType.Soap,guid);         Response.Write("USER_ID = "+Session["USER_ID"].ToString()+"<br />");         Response.Write("USER_NAME = "+Session["USER_NAME"].ToString()+"<br />");         Response.Write("AUTH_GUID = " + Session["AUTH_GUID"].ToString() + "<br />");     } }

 

此例子只是提供了一种解决思路,在应用过程中应根据项目不同进行调整及详细设计。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值