Memcache+Cookie替代Session解决方案(MVC版)

阅读目录

  • 开始
  • 通过IHttpModule注册过滤管道方式
  • 通过BaseController
  • 关于滑动过期

两种方式

回到顶部

通过IHttpModule注册过滤管道方式

具体实现如下:

声明一个类CheckLoginModule.cs它继承自IHttpModule

在请求管道的第9个事件 即获得用户状态的事件中 注册OnRequest事件  判断Memcached中是否存在对应客户端SessionId的用户信息  不存在则意味服务端Session失效

接着判断是否具有保留一周的Cookie(通常网站"记住我一周"的功能) 如果存在 根据Cookie信息获取用户信息 写入Memcached中

假设当用户请求/home/index 页面时 我们要求用户必须登录 即服务端有该用户信息 不存在则跳转至/home/login页面进行登录操作

CheckLoginModule.cs文件内容如下:

using System;
using System.Web;
using MvcMamcache.Models;

namespace MvcMamcache.Common {
    public class CheckLoginModule : IHttpModule {
        #region IHttpModule 成员

        public void Init(HttpApplication context) {
            context.AcquireRequestState += new EventHandler(OnRequest);
        }

        public void OnRequest(object source, EventArgs e) {
            HttpApplication application = source as HttpApplication;//得到Application
            HttpContext context = application.Context;//得到请求上下文.
            Uri url = context.Request.Url;//得到当前请求的URL

            if(url.AbsolutePath.ToLower() == "/home/index") {
                var httpCookie = context.Request.Cookies["SessionId"];
                if(httpCookie == null || Common.MemCacheHelper.GetValue(httpCookie.Value) == null) {//Session会话过期
                    //是否保留7天
                    if(context.Request.Cookies["ui1"] == null || context.Request.Cookies["ui2"] == null) {
                        context.Response.Redirect("/home/login");
                    } else {
                        //根据Cookie中保存的用户名与密码至数据库获取UserInfo对象  这里直接new
                        UserInfo userInfo = new UserInfo() {
                            LoginId = context.Request.Cookies["ui1"].Value,
                            LoginPwd = context.Request.Cookies["ui2"].Value
                        };
                        var sessionId = Guid.NewGuid().ToString();
                        context.Response.Cookies["SessionId"].Value = sessionId;
                        Common.MemCacheHelper.Insert(sessionId, userInfo);
                    }
                }
            }
        }

        public void Dispose() {
            throw new NotImplementedException();
        }
        #endregion
    }
}

需要将此过滤Module在Web.Config文件中进行配置

      <httpModules>
          <add name="CheckLoginModule"
               type="MvcMamcache.Common.CheckLoginModule"/>
      </httpModules>

Home控制器中Index与Login方法的调整

回到顶部

通过BaseController

自定义的父类控制器  它继承自Controller 在控制器Initialize中 进行校验  并声明LoginUserInfo属性保存用户信息供所有子Controller使用

using System;
using System.Web.Mvc;
using MvcMamcache.Models;

namespace MvcMamcache.Common {
    public class BaseController : Controller {
        protected UserInfo LoginUserInfo {
            get;
            set;
        }

        protected override void Initialize(System.Web.Routing.RequestContext requestContext) {
            base.Initialize(requestContext);
            if(requestContext.HttpContext.Request.Cookies["SessionId"] != null) {
                string guid = requestContext.HttpContext.Request.Cookies["SessionId"].Value;
                object obj = Common.MemCacheHelper.GetValue(guid);//根据Cookie的值从缓存中取出数据.
                if(obj != null) {
                    UserInfo model = obj as UserInfo;
                    LoginUserInfo = model;
                } else {
                    CheckCookieSevenDay(requestContext);//7天Cookie检验
                }
            } else {
                Response.Redirect("/home/login");
            }
        }

        private void CheckCookieSevenDay(System.Web.Routing.RequestContext requestContext) {
            var context = requestContext.HttpContext;
            if(context.Request.Cookies["ui1"] == null || context.Request.Cookies["ui2"] == null) {
                context.Response.Redirect("/home/login");
            } else {
                //根据Cookie中保存的用户名与密码至数据库获取UserInfo对象  这里直接new
                UserInfo userInfo = new UserInfo() {
                    LoginId = context.Request.Cookies["ui1"].Value,
                    LoginPwd = context.Request.Cookies["ui2"].Value
                };
                var sessionId = Guid.NewGuid().ToString();
                context.Response.Cookies["SessionId"].Value = sessionId;
                Common.MemCacheHelper.Insert(sessionId, userInfo);
            }
        }
    }
}

需要用户状态校验的控制器中

using System.Web.Mvc;
using MvcMamcache.Common;

namespace MvcMamcache.Controllers {
    public class AdminController : BaseController {
        //
        // GET: /Admin/

        public ActionResult Index() {
            ViewBag.UserName = LoginUserInfo.LoginId;
            return View();
        }

    }
}

回到顶部

关于滑动过期

上述第一种方式中我们通过设置了缓存过期时间为20分钟 但这是绝对过期时间 而非滑动过期 若想实现滑动过期也好办 通过Memcached的Replace(key,value,newTimeSpan)来更新失效时间

不在原有代码上调整,这里提供思路如下:

f(Common.MemCacheHelper.GetValue("GetNow") == null) {
               Common.MemCacheHelper.Insert("GetNow", DateTime.Now, DateTime.Now.AddMinutes(1));
               ViewBag.Msg = "新增时间" + Common.MemCacheHelper.GetValue("GetNow").ToString() + "失效时间应该在:" + ((DateTime)Common.MemCacheHelper.GetValue("GetNow")).AddMinutes(1);
           } else {
               Common.MemCacheHelper.Replace("GetNow", DateTime.Now, DateTime.Now.AddMinutes(30));
               ViewBag.Msg = "替换时间" + Common.MemCacheHelper.GetValue("GetNow").ToString() + "失效时间应该在:" + ((DateTime)Common.MemCacheHelper.GetValue("GetNow")).AddMinutes(30);

当然session的替代方案远不止使用Memcached 还可以通过Nosql非关系型数据库,话说ManagDB的效率相当称赞

点击下载资源

时间: 2024-07-31 14:31:44

Memcache+Cookie替代Session解决方案(MVC版)的相关文章

Memcache+cookie实现模拟session

上一片讲到Memcached在Windows上的安装,和用Telnet工具进行命令操作,在稍微了解了原理之后,我也就开始尝试着用程序来对Memcached进行操作.这一篇分为两个部分,第一部分是用.net程序对Memcached进行操作,第二部分是结合mvc实现一个分布式的缓存系统. 一..net程序对Memcached进行操作 想要用.net操作Memcached,首先我们的去下载.NET客户端类库:https://sourceforge.net/projects/memcacheddotne

[MVC学习笔记]6. 使用Memcache+Cookie解决分布式系统共享登录状态

      为了解决单机处理的瓶颈,增强软件的可用性,我们需要将软件部署在多台服务器上启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立的服务器上,或通过负载均衡技术(如:DNS轮询.Radware.F5.LVS等)让多个频道共享一组服务器.当我们将网站程序分部到多台服务器上后,由于Session受实现原理的局限,无法跨服务器同步更新Session,使得登录状态难以通过Session共享.       我们使用MemCache+Cookie方案来解决分布式系统共享登录状态的问题.

cookie 和 session

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session. 1.1  Cookie机制 在程序中,会话跟踪是很重要的事情.理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个

理解Cookie和Session机制

转自:http://my.oschina.net/xianggao/blog/395675 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session. Cookie机制 Cookie技术是客户端的解决方案,Cooki

理解Cookie和Session机制(转)

目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie的有效期 Cookie的修改.删除 Cookie的域名 Cookie的路径 Cookie的安全属性 JavaScript操作Cookie 案例:永久登录 Session机制 什么是Session 实现用户登录 Session的生命周期 Session的有效期 Session的常用方法 Session

Cookie和Session机制详解

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. ?Cookie是客户端技术,程序(服务器)把每个用户的数据以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着

Apache shiro集群实现 (六)分布式集群系统下的高可用session解决方案---Session共享

Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro Authentication) Apache shiro集群实现 (四)shiro授权(Authentication)--访问控制 Apache shiro集群实现 (五)分布式集群系统下的高可用session解决方案 Apache shiro集群实现 (六)分布式集群系统下的高可用session

ASP.NET Cookie和Session

Cookie和Session C#在服务器,JS在客户端 客户端验证不能代替服务端验证 Http HTTP属于应用层,HTTP 协议一共有五大特点:1.支持客户/服务器模式;2.简单快速;3.灵活;4.无连接;5.无状态. 无状态 无状态是指协议对于事务处理没有记忆能力.缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大.另一方面,在服务器不需要先前信息时它的应答就较快. Http协议是无状态的,不会记得上次和网页“发生了什么”. HTTP协议是无状态的

【转】Cookie和Session区别和联系详解

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session. 1.1  Cookie机制 在程序中,会话跟踪是很重要的事情.理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个