• 基于Redis缓存的Session共享(附源码)


        在上一篇文章中我们研究了Redis的安装及一些基本的缓存操作,今天我们就利用Redis缓存实现一个Session共享,基于.NET平台的Seesion共享用的最多的应该是SQLServer数据库实现,我之前参与的一个项目么么亲子社区就是用的SQLSERVER实现不同子域名之间的Session共享。先打个广告嘿嘿,么么亲子网:enmuo.comi.enmuo.com就是通过SQLSERVER实现Session共享 欢迎大家访问。

    该片文章主要介绍主域名跟不同子域名之间的Session信息共享。

    纠正上一篇文章中关于RredisHelper类中的一个错误,就是要把设置缓存过期时间的代码放在设置完缓存值的后面,要不当第一次给该缓存键赋值的时候设置的缓存时间不管用,这个我也不知道为真么,具体修改如下:

    /// <summary>
    
            /// 添加单个实体到链表中
    
            /// </summary>
    
            /// <typeparam name="T"></typeparam>
    
            /// <param name="listId"></param>
    
            /// <param name="Item"></param>
    
            /// <param name="timeout"></param>
    
            public void AddEntityToList<T>(string listId, T Item, int timeout = 0)
    
            {
    
                IRedisTypedClient<T> iredisClient = Redis.As<T>();
    
              
    
                var redisList = iredisClient.Lists[listId];
    
                redisList.Add(Item);
    
                iredisClient.Save();
    
                if (timeout >= 0)
    
                {
    
                    if (timeout > 0)
    
                    {
    
                        secondsTimeOut = timeout;
    
                    }
    
                    Redis.Expire(listId, secondsTimeOut);
    
                }
    View Code

    下面我们开始进入正题,首先介绍一下CookieSession的关系

        我们都知道Session是存在Server端,Cookie是存在用户浏览器本地或内存中,用户在发起一个HTTP请求时,在请求的Header中会有Cookie信息,而Cookie中有一个ASP.NET_Sessionid的值,我们就是通过这个值获取到服务器端对应的Session信息。如下图所示:

     

    说明:图片中的token值是我的另一篇博文中用到的,本篇文章中不涉及该值。

    下面介绍一下我的思路

    1.  用户在给Session赋值的操作的时候我们可以为用户生成一个唯一的cookie值作为sessionID存储在用户的客户端,该cookie的key值可以自己命名,将该cookie值作为缓存的键和Session值一起存入到Redis缓存中。当然我们也可以直接用cookie中ASP.NET_Sessionid的值。
    2.  用户使用Session值得时候就可以根据cookie中的sessionId值在缓存中取出数据即可。

    程序实现逻辑:

    1、  我们新建一个如下项目,只用关注红线圈住的,其他没有用

     

    •  CookieHelper.cs Cookie操作,主要获取或生成SessionID值
    •  RredisHelper.cs 缓存操作,详见上一篇博文
    •  SessionHelper.cs 封装的Session操作

    2、  CookieHelper.cs文件

    在该文件中我们首先定义一个常量const string RedisSessionCookiesId = "RedisSessionCookiesId";作为cookie中存储SessionId的健。我们用Guid.NewGuid()

    生成一个唯一的值存储在cookie中作为SessionId的值,我们给cookie的Domain属性复制 "session.com",作为共享cookie的顶级域名。

    具体代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    
    namespace LONG.Common
    {
       public  class CookieHelper
        {
           //sessionId 的Key
            const string RedisSessionCookiesId = "RedisSessionCookiesId";
           /// <summary>
           /// 获取设置SessionID值
           /// </summary>
           /// <returns></returns>
            public static string CreatSessionCookie()
            {
                if (HttpContext.Current.Request.Cookies[RedisSessionCookiesId] != null)
                {
                    return HttpContext.Current.Request.Cookies[RedisSessionCookiesId].Value.ToString();
                }
                else
                {
                    Guid guid = Guid.NewGuid();
                    HttpCookie cokie = new HttpCookie(RedisSessionCookiesId);
                    cokie.Value = guid.ToString();
                    cokie.Expires = System.DateTime.Now.AddDays(1);
                    cokie.Domain = "session.com";
                    //cokie.Path = "/";
                    cokie.HttpOnly = true;
                    HttpContext.Current.Response.Cookies.Add(cokie);
                    return guid.ToString();
                }
            }
        }
    }
    View Code

    3、  RredisHelper.cs文件不做介绍,详见:http://www.cnblogs.com/lc-chenlong/archive/2013/07/26/3218157.html

    4、 SessionHelper.cs 文件

    通过索引器实现Session[“XX”]的取值赋值操作。对索引器不了解的童鞋可以百度一下。

    因为在一个项目中我们可以定义很多Session,比如Session[“name”]、Session[“url”]等,然而SessionID却只有一个值,那么我们怎么区分这些Session值呢,我们可以用SessionID+”_”+Session索引值实现,如:SessionID+”_name”、 SessionID+”_url”。

      代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    
    
    namespace LONG.Common
    {
        public class SessionHelper
        {
            
           public   RedisHelper Redis = new RedisHelper(true);
            public object this[string key]
            {
                get 
                {
                    key = CookieHelper.CreatSessionCookie() + "_" + key;
                    
                    //距离过期时间还有多少秒
                    long l = Redis.TTL(key);
                    return Redis.Get<object>(key); 
                }
                set 
                {
                    SetSession(key,value);
                }
            }
            public   void SetSession(string key,object value)
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    throw new Exception("Key is Null or Epmty");
                }
                key = CookieHelper.CreatSessionCookie() + "_"+key;
                Redis.Set<object>(key, value,60*3);
            }
            public string SessionId
            {
                get { return  CookieHelper.CreatSessionCookie();}
            }
        }
    }
    View Code

    对Session共享测试

    1、新建两个web项目

     

    2、我们在WebForm1.aspx.cs中添加如下代码:

     protected void Page_Load(object sender, EventArgs e)
            {
                test();
            }
            public void test()
            {
                SessionHelper Session = new SessionHelper();
                if (Session["user"] == null)
                {
                    Session["user"] = "eric";
                }
                //为了展示两个session的过期时间不一样,让线程休眠2s
                System.Threading.Thread.Sleep(2000);
                if(Session["url"]==null)
                {
                    Session["url"] = "http://baidu.com";
                }
                //Session["user"] = "qwewrwe";
                string text = string.Format("session['user']的值为:{0},距离过期时间:{1}秒", Session["user"].ToString(), Session.Redis.TTL(Session.SessionId + "_user"));
                text += "<br />";
                text += string.Format("session['url']的值为:{0},距离过期时间:{1}秒", Session["url"].ToString(), Session.Redis.TTL(Session.SessionId + "_url"));
                Response.Write(text);
    
            }
    View Code

    3、在Default.aspx中添加如下代码:

     public partial class _Default : System.Web.UI.Page
        {
            SessionHelper Session = new SessionHelper();
            
            protected void Page_Load(object sender, EventArgs e)
            {
                   Label1.Text= Session["user"].ToString()+"___"+Session["url"].ToString();
                
            }
            protected void Button1_Click(object sender, EventArgs e)
            {
                //改变Session["user"]的值
                Session["user"] = TextBox1.Text;
                Label1.Text = Session["user"].ToString()+"___"+Session["url"].ToString();
            }
        }
    View Code

    4、我在IIS想新建了两个项目:session.com(对应WebForm1.aspx项目)和b.session.com(对应Default.aspx项目)

     

     

    5、运行session.com下过如下:

     

    6、运行 b.session.com,我们发现我们获取到session.com站点的session值

     

    7、b.session.com在文本框中输入”陈龙”并点击【改变Session[user] 值】按钮。如下图:

     

    8、刷新session.com发现session[‘user’]的值已经改变,而且过期时间也被刷新。

     

    9、等到session.com 页面session[‘url’]的过期时间为0时刷新b.session.com

     

     

    说明Session值已过期。

    整个例子已经写完,如果文中有说的不对的地方欢迎指正。

    点击下载源码

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    JavaScript-Runoob:JavaScript 对象
    JavaScript-Runoob:JavaScript 数据类型
    JavaScript-Runoob:JavaScript 变量
    JavaScript-Runoob:JavaScript 注释
    JavaScript-Runoob:JavaScript 语句
    从word中复制内容包含图片到tinymce编辑器中
    从word中复制内容包含图片到xheditor编辑器中
    从word中复制内容包含图片到kindeditor编辑器中
    从word中复制内容包含图片到ckeditor编辑器中
    从word中复制内容包含图片到fckeditor编辑器中
  • 原文地址:https://www.cnblogs.com/lc-chenlong/p/3221003.html
Copyright © 2020-2023  润新知