为什么要去session:多服务器不能共享,虽然有进程外session,但是性能很低
session局限性:
1.占用资源高
2.管理不方便
3.跨域、跨主机支持性很麻烦
4.性能差
5.容易产生系统垃圾
6.不稳定性,如:服务器重启后SESSION容易丢失
向客户端保存cookie:Response.Cookies.Add(HttpCookie的对象);
向服务端提交cookie:Request.Cookies[key];
设置属性:Response.Cookies[key].Expired=...;
小问题:这里也需要引入log4net,但是两个程序集的版本是不一致的,为了能够并存,可以到log4net源码中重新生成一个其它名称的程序集,如log4net_log
步骤:
(1)在cookie中存储guid值,每次请求上传这个值
(2)使用客户端对象,根据guid作为键进行查找对象
实例:分布式缓存去session登陆
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using HM13OA.Common; using HM13OA.UI.Models; namespace HM13OA.UI.Controllers { public class MyBaseController : Controller { protected override void OnAuthorization(AuthorizationContext filterContext) { //return; //base.OnAuthorization(filterContext); //去session,使用分布式缓存完成登录 //if (Session["UserLogin"] == null) //{ // filterContext.Result=new RedirectResult(Url.Action("Index","UserLogin")); //} //1、获取客户端标识 if (Request.Cookies.Get("loginId") == null) { filterContext.Result = new RedirectResult(Url.Action("Index", "UserLogin")); return; } string key=Request.Cookies.Get("loginId").Value; //2、与分布式缓存进行通信,获取对象 MmHelper helper=new MmHelper(); UserInfoViewModel userInfoViewModel = helper.Get(key) as UserInfoViewModel; //3、判断是否登录 if (userInfoViewModel == null) { filterContext.Result = new RedirectResult(Url.Action("Index", "UserLogin")); return; } //4、设置超时滑动时间 helper.Set(key, userInfoViewModel, DateTime.Now.AddMinutes(20)); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using DotNetOpenAuth.OpenId.Extensions.AttributeExchange; using HM13OA.Common; using HM13OA.IService; using HM13OA.Model; using HM13OA.UI.Models; namespace HM13OA.UI.Controllers { public class UserLoginController : Controller { public IUserInfoService UserInfoService { get; set; } public ActionResult Index() { return View(); } public ActionResult ValidateCode() { ValidateCode vCode = new ValidateCode(); string code = vCode.CreateValidateCode(4); Session["ValidateCode"] = code; byte[] bytes = vCode.CreateValidateGraphic(code); return File(bytes, @"image/jpeg"); } [HttpPost] public ActionResult Login(UserInfoViewModel userInfo) { string result = "no"; //判断是否是一个正常的请求 if (Session["ValidateCode"] == null || Session["ValidateCode"].ToString() == "") { return Content("请正常请求"); } string vcode = Request["vCode"]; //先匹配验证码 if (Session["ValidateCode"].ToString().Equals(vcode,StringComparison.InvariantCultureIgnoreCase)) { //根据用户名密码进行查询 if (UserInfoService.Login(new UserInfo() { UserName = userInfo.UserName, UserPwd = userInfo.UserPwd })) { result = "ok"; //去session,改成分布式缓存 //Session["UserLogin"] = userInfo; //使用分布式缓存进行登录操作 //1、创建标识 string key = Guid.NewGuid().ToString(); //2、向客户端写标识 Response.Cookies.Add(new HttpCookie("loginId",key)); //3、向分布式缓存服务器写信息 MmHelper helper=new MmHelper(); helper.Set(key, userInfo, DateTime.Now.AddMinutes(20)); } else { result = "用户名或密码错误"; Session["ValidateCode"] = ""; } } else { //验证码不匹配 result = "验证码错误"; Session["ValidateCode"] = ""; } return Content(result); } public ActionResult Logout() { //去session //Session["UserInfo"] = null; //使用分布式缓存的用户注销 if (Request.Cookies.Get("loginId") != null) { string key = Request.Cookies.Get("loginId").Value; //1、更新客户端cookie //Response.Cookies["loginId"].Expires = DateTime.Now.AddMinutes(-1); //2、销毁分布式缓存中的对象 MmHelper helper=new MmHelper(); helper.Delete(key); } return RedirectToAction("Index"); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Memcached.ClientLibrary; namespace HM13OA.Common { public partial class MmHelper { private MemcachedClient client; public MmHelper() { string[] ips = System.Configuration.ConfigurationManager.AppSettings["MemcachedServers"].Split(','); SockIOPool pool = SockIOPool.GetInstance(); pool.SetServers(ips); pool.Initialize(); client=new MemcachedClient(); client.EnableCompression = true; } public bool Set(string guid,object value,DateTime expiryTime) { return client.Set(guid, value, expiryTime); } public object Get(string guid) { return client.Get(guid); } public bool Delete(string guid) { return client.Delete(guid); } } }