在官网上下载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;
}
}
}
}
}