在官网上下载MemCach的dll根据文档配置MemCachHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Memcached.ClientLibrary; namespace Common { public static class MemcachHelper { //缓存 全局共享的东东,所有安装了服务的主机就是数据源,他内部有个算法分配到什么数据都不用我们管了。 private static MemcachedClient mc = null; static MemcachHelper() { string[] serverlist = { "127.0.0.1:11211"};//写到配置文件中。 //初始化池 SockIOPool pool = SockIOPool.GetInstance(); pool.SetServers(serverlist); pool.InitConnections = 3; pool.MinConnections = 3; pool.MaxConnections = 5; pool.SocketConnectTimeout = 1000; pool.SocketTimeout = 3000; pool.MaintenanceSleep = 30; pool.Failover = true; pool.Nagle = false; pool.Initialize(); // 获得客户端实例 mc = new MemcachedClient(); mc.EnableCompression = false; } /// <summary> /// 设置缓存的值 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public static void Set(string key, object value) { mc.Set(key, value); } /// <summary> /// 设置缓存的值和日期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="datetime"></param> public static void Set(string key, object value, DateTime datetime) { mc.Set(key, value, datetime); } /// <summary> /// 获取缓存的值 /// </summary> /// <param name="key"></param> /// <returns></returns> public static object Get(string key) { return mc.Get(key); } /// <summary> /// 删除指定的键值对 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Delete(string key) { //不存在删除失败 if (!mc.KeyExists(key)) { return false; } //存在删除 return mc.Delete(key); } } }
这里的数组填写的是子服务器的ip和端口 在缓存服务器上开启了服务,MemCach就会自动根据一个算法选择一个缓存服务器把数据存在其中
好了现在我们开始模拟Session 构造和Session类似的结构如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Memcached.ClientLibrary; using System.Web; namespace Common { public class MemSession { private static MemSession MySession = new MemSession(); public static MemSession GetSession() { return MySession; } public object this[string key] { set { HttpContext context = HttpContext.Current; string id= null; if (context.Request.Cookies["AspNet_SessionId"] != null) { id = context.Request.Cookies["AspNet_SessionId"].Value; } //第一次设置session id代表这次会话 else { context.Response.Clear(); HttpCookie cookie = new HttpCookie("AspNet_SessionId"); id = Guid.NewGuid().ToString().Substring(0, 12); cookie.Value = id; //设置不会出现异常大胆输出 context.Response.Cookies.Add(cookie); //设置值,此时所有子服务器 都可以从这台缓存服务器中拿到值 } MemSessionDic.Set(id,key,value); } get { HttpContext context = HttpContext.Current; HttpCookie cookie = context.Request.Cookies["AspNet_SessionId"]; string value = null; if (cookie != null) { value = cookie.Value; } return MemSessionDic.Get(value, key); } } } }
好了核心类出来了。注释已经写的很清楚了我就不多写了 这里要注意的是我使用了饿汉模式这是因为HttpContext.Current.Session 是唯一的 如果不是唯一的请求过来 是不知道找哪个键值对的 MemSessionDic的核心代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Common { //在子服务器上处理设置session public class MemSessionDic { public static Dictionary<string, object> dic = new Dictionary<string, object>(); public static void Set(string id, string key, object value) { //数据字典必须从缓存服务器中获取!存在缓存器中的字典被序列化了不会丢失,子服务器有sessionid完全可以从缓存服务器中拿到字典 Dictionary<string,object> dic = MemcachHelper.Get(id) as Dictionary<string,object>; //如果是第一次设置 if (dic == null) { dic = new Dictionary<string, object>(); dic.Add(key, value); } //存在这个字典而且如果字典中存在这个key else if (dic.ContainsKey(key)) { //覆盖 dic[key] = value; } //存在这个字典而且如果是第一次设置这个key的值 else { //添加进去 dic.Add(key, value); } //从新存进去 设置过期时间为20分钟如果20分钟过了字典会被清空 MemcachHelper.Set(id, dic, DateTime.Now.AddMinutes(20)); } /// <summary> /// 获取session的值 /// </summary> /// <param name="id">sessionid</param> /// <param name="key">session键的名称</param> /// <returns></returns> public static object Get(string id, string key) { //没有sessionid了等同与浏览器关掉了sessionid是cookie在内存中 if (id == null) { return null; } //有id从缓存服务器中取出数据,或者数据是否过期,还怕有人伪造sessionid Dictionary<string, object> dic = MemcachHelper.Get(id) as Dictionary<string, object>; if (dic == null) { return null; //throw new Exception("sessionid不正确"); } else { if (dic.ContainsKey(key)) { return dic[key]; } //缓存服务器里是否没有key的数据 else { return null; } } } } }