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

两种方式
 

通过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)来更新失效时间
不在原有代码上调整,这里提供思路如下:
if(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的效率相当称赞

点击下载资源

转载于:https://www.cnblogs.com/piziyimao/archive/2013/01/29/2882236.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值