跨站点共享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
{

    
/* *****************************
     * 
     *  Author      :    Xiaojun Liu
     *  Create Date :    2007.11.09
     *  Description :
     * 
     * *****************************
    
*/



    
/// <summary>
    
/// 格式化操作器
    
/// </summary>

    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 />");
    }

}

 

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

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值