分布式缓存HttpRuntime.cache应用到单点登陆中_优化登陆
以前的设计方案,是我们在数据库中放一个表,用作存储验证登陆成功的用户,并且生成用户TOKEN(令牌)
分布式缓存+集群的解决方案图:
相应的代码:
DE层中配置文件:
<configuration> <appSettings> <!--集群相关开始--> <!--集群IP组--> <add key= "ClusterGroupAddr" value= "192.168.1.165,10.132.41.52" /> <!--当前的Web站点名称--> <add key= "WebSiteName" value= "HttpRuntimeCacheService" /> <!-- 集群相关截止 --> </appSettings> <system.serviceModel> <bindings> <basicHttpBinding> <binding name= "CacheServiceSoap" closeTimeout= "00:01:00" openTimeout= "00:01:00" receiveTimeout= "00:10:00" sendTimeout= "00:01:00" allowCookies= "false" bypassProxyOnLocal= "false" hostNameComparisonMode= "StrongWildcard" maxBufferSize= "65536" maxBufferPoolSize= "524288" maxReceivedMessageSize= "65536" messageEncoding= "Text" textEncoding= "utf-8" transferMode= "Buffered" useDefaultWebProxy= "true" > <readerQuotas maxDepth= "32" maxStringContentLength= "8192" maxArrayLength= "16384" maxBytesPerRead= "4096" maxNameTableCharCount= "16384" /> <security mode= "None" > <transport clientCredentialType= "None" proxyCredentialType= "None" realm= "" /> <message clientCredentialType= "UserName" algorithmSuite= "Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address= "http://localhost/HttpRuntimeCacheService/CacheService.asmx" binding= "basicHttpBinding" bindingConfiguration= "CacheServiceSoap" contract= "CacheService.CacheServiceSoap" name= "CacheServiceSoap" /> </client> </system.serviceModel> </configuration> |
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(); /// <summary> /// 发送用于同步集群中的Cache数据 /// </summary> /// <param name="param">Cache数据</param> 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 ; } } } /// <summary> /// 用于同步集群中的Cache数据 /// </summary> /// <param name="param">Cache数据</param> /// <param name="operation">Cache操作类型</param> 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; } } } /// <summary> /// Cache同步操作类型 /// </summary> 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; } /// <summary> /// 在Cache中查询在线用户 /// </summary> /// <param name="param">在线用户参数</param> public List<LoginStatusParam> QueryLoginStatus(LoginStatusParam param) { List<LoginStatusParam> result = new List<LoginStatusParam>(); List<LoginStatusParam> 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<LoginStatusParam>(); return result; } // 将Cache中的项转换成List private List<LoginStatusParam> ConvertCacheItem() { List<LoginStatusParam> plist = new List<LoginStatusParam>(); 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 /// <summary> /// 在Cache中增加在线用户 /// </summary> /// <param name="param">在线用户参数</param> 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; } } } } |
windows技术爱好者
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构