以前的设计方案,是我们在数据库中放一个表,用作存储验证登陆成功的用户,并且生成用户TOKEN(令牌)
分布式缓存+集群的解决方案图:
相应的代码:
DE层中配置文件:
CacheBase.cs 缓存基类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization.Formatters.Binary; using System.Security; using System.Web.Caching; using System.Web; using System.ServiceModel; using System.Reflection; using HttpRuntimeCacheDE.CacheService; namespace HttpRuntimeCacheDE.Cache { public class CacheBase { private CacheServiceSoapClient client = null; private CacheService.LoginStatusParam cParam = new CacheService.LoginStatusParam(); private CacheService.CacheOperation cOperation = new CacheService.CacheOperation(); ////// 发送用于同步集群中的Cache数据 /// /// Cache数据 public void SendCacheData(CacheParam param, CacheOperation operation) { string[] ips = CacheConfig.ClusterGroupAddr; foreach (string ip in ips) { try { client = new CacheService.CacheServiceSoapClient(); EndpointAddress address = new EndpointAddress("http://" + ip + @"/" + CacheConfig.WebSiteName + "/CacheService.asmx"); client.Endpoint.Address = address; RemoteParamConvert(cParam, param); switch (operation) { case CacheOperation.Add: cOperation = CacheService.CacheOperation.Add; break; case CacheOperation.Edit: cOperation = CacheService.CacheOperation.Edit; break; case CacheOperation.Delete: cOperation = CacheService.CacheOperation.Delete; break; default: break; } client.GetCacheData(cParam, cOperation); } catch { continue; } } } ////// 用于同步集群中的Cache数据 /// /// Cache数据 /// Cache操作类型 public void SyncCacheData(CacheParam param, CacheOperation operation) { switch (operation) { case CacheOperation.Add: AddCache(param); break; case CacheOperation.Edit: EditCache(param); break; case CacheOperation.Delete: DeleteCache(param); break; default: break; } } // 增加Cache数据 protected virtual void AddCache(CacheParam param) { string key = BuildCacheKey(param); HttpRuntime.Cache.Add(key, param, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High, null); } // 修改Cache数据 protected virtual void EditCache(CacheParam param) { string key = BuildCacheKey(param); HttpRuntime.Cache.Remove(key); AddCache(param); } // 删除Cache数据 protected virtual void DeleteCache(CacheParam param) { string key = BuildCacheKey(param); HttpRuntime.Cache.Remove(key); } // 生成在线的Cache Key protected virtual string BuildCacheKey(CacheParam param) { return ""; } // 将本地参数转换成远程调用的参数 private void RemoteParamConvert(object sourceObj, object targetObj) { try { PropertyInfo[] sourceInfo = sourceObj.GetType().GetProperties(); PropertyInfo[] targetInfo = targetObj.GetType().GetProperties(); for (int i = 0; i < sourceInfo.Length; i++) { if (sourceInfo[i].Name == targetInfo[i].Name) { object targetValue = targetInfo[i].GetValue(targetObj, null); if (!ParamFunc.Judgement(targetValue)) continue; sourceInfo[i].SetValue(sourceObj, targetValue, null); } } } catch (Exception ex) { throw ex; } } } ////// Cache同步操作类型 /// public enum CacheOperation { Add, Edit, Delete } }
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using System.Web.Caching; namespace HttpRuntimeCacheDE.Cache { public class CacheFunc:CacheBase { protected override string BuildCacheKey(CacheParam param) { LoginStatusParam lsparam = param as LoginStatusParam; return param.GetType().Name.ToString() + "&" + lsparam.SysLoginStatusID + "&" + lsparam.LoginName; } ////// 在Cache中查询在线用户 /// /// 在线用户参数 public ListQueryLoginStatus(LoginStatusParam param) { List result = new List (); List plist = ConvertCacheItem(); var loginResult = from c in plist where 1 == 1 && (!Judgement(param.SysLoginStatusID) ? true : c.SysLoginStatusID == param.SysLoginStatusID) && (!Judgement(param.SysOrganizationID) ? true : c.SysOrganizationID == param.SysOrganizationID) && (!Judgement(param.SysServiceCenterID) ? true : c.SysServiceCenterID == param.SysServiceCenterID) && (!Judgement(param.LoginName) ? true : c.LoginName == param.LoginName) && (!Judgement(param.LoginTime) ? true : c.LoginTime == param.LoginTime) && (!Judgement(param.LastHandleTime) ? true : c.LastHandleTime == param.LastHandleTime) && (!Judgement(param.FullName) ? true : c.FullName == param.FullName) && (!Judgement(param.LoginToken) ? true : c.LoginToken == param.LoginToken) select c; result = loginResult.ToList (); return result; } // 将Cache中的项转换成List private List ConvertCacheItem() { List plist = new List (); IDictionaryEnumerator CacheEnum = HttpRuntime.Cache.GetEnumerator(); while (CacheEnum.MoveNext()) { if (CacheEnum.Value is LoginStatusParam) plist.Add(CacheEnum.Value as LoginStatusParam); } return plist; } public string SysUserLogin(LoginStatusParam param) { AddLoginStatus(param); param = QueryLoginStatus(param).First(); return param.LoginToken; } #region AddMethod /// /// 在Cache中增加在线用户 /// /// 在线用户参数 public void AddLoginStatus(LoginStatusParam param) { Random random = new Random(); param.SysLoginStatusID = random.Next().ToString(); SyncCacheData(param, CacheOperation.Add); SendCacheData(param, CacheOperation.Add); } #endregion private bool Judgement(object obj) { try { if (obj != null && obj != DBNull.Value) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } } }