还记得上面提到的问题吗?如何把用户的状态信息保存起来,共享给这三台服务器?下面通过代码,给大家介绍ASP.Net MVC 4中如何使用Memcached,开始吧!
项目结构:

项目中需要引用Memcached的dll,如下:

1、首先准备好工具类:
MemcacheHelper:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using Memcached.ClientLibrary;
6
7 namespace WebDemo.Models
8 {
9 public static class MemcacheHelper
10 {
11 private static MemcachedClient mc;
12
13 static MemcacheHelper()
14 {
15 //通过客户端来进行memcached的集群配置,在插入数据的时候,使用一致性哈希算法,将对应的value值存入Memcached
16 String[] serverlist = { "127.0.0.1:11211" };
17
18 // 初始化Memcached的服务池
19 SockIOPool pool = SockIOPool.GetInstance("test");
20 //设置服务器列表
21 pool.SetServers(serverlist);
22 //各服务器之间负载均衡的设置比例
23 pool.SetWeights(new int[] { 1 });
24 pool.Initialize();
25 //创建一个Memcached的客户端对象
26 mc = new MemcachedClient();
27 mc.PoolName = "test";
28 //是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
29 mc.EnableCompression = false;
30
31 }
32 /// <summary>
33 /// 插入值
34 /// </summary>
35 /// <param name="key">建</param>
36 /// <param name="value">值</param>
37 /// <param name="expiry">过期时间</param>
38 /// <returns></returns>
39 public static bool Set(string key, object value,DateTime expiry){
40 return mc.Set(key, value, expiry);
41 }
42 /// <summary>
43 /// 获取值
44 /// </summary>
45 /// <param name="key"></param>
46 /// <returns></returns>
47 public static object Get(string key)
48 {
49 return mc.Get(key);
50 }
51 }
52 }
BaseController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebDemo.Models;
namespace WebDemo.Controllers
{
public class BaseController : Controller
{
//用来保存当前的用户信息
public UserInfo LoginUser { get; set; }
//通过过滤器来实现每个页面的检查
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
//从cookie中获取咱们的 登录的sessionId
string sessionId = Request["sessionId"];
//如果sessionid为空值,则跳转到登录页面
if (string.IsNullOrEmpty(sessionId))
{
//return RedirectToAction("Login", "Logon");
Response.Redirect("/Logon/Index");
}
object obj = MemcacheHelper.Get(sessionId);
UserInfo user = obj as UserInfo;
if (user == null)
{
Response.Redirect("/Logon/Index");
}
LoginUser = user;
//实现session的滑动机制
MemcacheHelper.Set(sessionId, user, DateTime.Now.AddMinutes(20));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Memcached.ClientLibrary;
namespace WebDemo.Controllers
{
public class MemcachedController : BaseController
{
//
// GET: /Memcached/
public ActionResult Index()
{
//初始化memcached 服务器端集群列表。
String[] serverlist = { "127.0.0.1:11211"};
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.GetInstance("test");
//设置怎么mem池连接点服务器端。
pool.SetServers(serverlist);
pool.Initialize();
//创建了一个mem客户端的代理类。
var mc = new MemcachedClient();
mc.PoolName = "test";
mc.EnableCompression = false;
//mc.Add("gz1", "我的女神宋智孝");
mc.Set("gz2", "hahaha", DateTime.Now.AddSeconds(15));
pool.Shutdown();//关闭连接池
return Content("ok");
}
}
}
2、models:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebDemo.Models
{
public class SchoolDbContext :DbContext
{
//使用EF的code-first,如果数据库中没有数据名字为MySqlDemo,则调用CreateIfNotExists方法会创建数据库
public SchoolDbContext()
: base("name=MySqlDemo")
{
this.Database.CreateIfNotExists();
}
public virtual DbSet<Student> Student { get; set; }
public virtual DbSet<UserInfo> UserInfo { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace WebDemo.Models
{
[Serializable]
public class Student
{
[StringLength(32)]
public virtual string SName { get; set; }
[StringLength(32)]
public virtual string Address { get; set; }
[Key]
public virtual int Id { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace WebDemo.Models
{
[Serializable]
public class UserInfo
{
public string UName { get; set; }
[Required]
[MaxLength(32)]
public string UPwd { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
}
}
3、接下来的代码是使用分布式缓存中最关键的一点:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebDemo.Models;
namespace WebDemo.Controllers
{
public class LogonController : Controller
{
//
// GET: /Logon/
public ActionResult Index()
{
return View();
}
public ActionResult Login(UserInfo user)
{
//创建一个DbContext对象,这样写不是很合理,先留个问题。(使用EF的code-first时需要注意的点)
SchoolDbContext dbContext =new SchoolDbContext();
var loginUser = dbContext.UserInfo.Where(u => u.UName.Equals(user.UName) && u.UPwd.Equals(user.UPwd)).FirstOrDefault();
if (loginUser == null)
{
return Content("用户名密码错误!");
}
else
{
Guid sessionId = Guid.NewGuid();//申请了一个模拟的GUID:SessionId
//把sessionid写到客户端浏览器里面去了(一定要把sessionid写到客户端,这样用户在访问其他web资源的时候,就会把cookie中的信息传给服务器,然后通过sessionid的key到Memcached中去取对应的值)
Response.Cookies["sessionId"].Value = sessionId.ToString();
//再把用户的信息插入到Memcached中
MemcacheHelper.Set(sessionId.ToString(), loginUser, DateTime.Now.AddMinutes(20));
return Content("ok");
}
}
public ActionResult ValidateCode()
{
ValidateCodeHelper helper =new ValidateCodeHelper();
string strCode = helper.CreateValidateCode(4);
Session["validateCode"] = strCode;
var byteData = helper.CreateValidateGraphic(strCode);
return File(byteData, "image/jpeg");
}
}
}
