using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; namespace APT.Infrastructure.Api { /// /// 缓存管理 /// 1.要可以查看所有的缓存 /// 2.要可以管理缓存中的数据,如清空,删除等 /// 3.可以预先加载 /// public class RedisManager { public int DbNum { get; } public ConnectionMultiplexer _conn; JsonSerializerSettings _jsonSetting; #region 构造函数 public RedisManager(int dbNum = 0) { DbNum = dbNum; _conn = RedisConfig.Instance; _jsonSetting = new JsonSerializerSettings(); _jsonSetting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; } #endregion 构造函数 #region String #region 同步方法 ///// ///// 保存单个key value ///// ///// Redis Key ///// 保存的值 ///// 过期时间 ///// //public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) //{ // key = AddSysCustomKey(key); // return Do(db => db.StringSet(key, value, expiry)); //} ///// ///// 保存多个key value ///// ///// 键值对 ///// //public bool StringSet(List> keyValues) //{ // List> newkeyValues = // keyValues.Select(p => new KeyValuePair(AddSysCustomKey(p.Key), p.Value)).ToList(); // return Do(db => db.StringSet(newkeyValues.ToArray())); //} ///// ///// 保存一个对象 ///// ///// ///// ///// ///// ///// //public bool StringSet(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) //{ // key = AddSysCustomKey(key); // string json = ConvertJson(obj); // return Do(db => db.StringSet(key, json, expiry)); //} ///// ///// 保存一个对象 ///// ///// ///// ///// ///// ///// //public bool StringSet(string key, T obj, DateTime expiry) //{ // key = AddSysCustomKey(key); // string json = ConvertJson(obj); // return Do(db => db.StringSet(key, json, expiry - DateTime.Now)); //} ///// ///// 获取单个key的值 ///// ///// Redis Key ///// //public string StringGet(string key) //{ // key = AddSysCustomKey(key); // return Do(db => db.StringGet(key)); //} ///// ///// 获取多个Key ///// ///// Redis Key集合 ///// //public RedisValue[] StringGet(List listKey) //{ // List newKeys = listKey.Select(AddSysCustomKey).ToList(); // return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); //} ///// ///// 获取一个key的对象 ///// ///// ///// ///// //public T StringGet(string key) //{ // key = AddSysCustomKey(key); // return Do(db => ConvertObj(db.StringGet(key))); //} ///// ///// 为数字增长val ///// ///// ///// 可以为负 ///// 增长后的值 //public double StringIncrement(string key, double val = 1) //{ // key = AddSysCustomKey(key); // return Do(db => db.StringIncrement(key, val)); //} ///// ///// 为数字减少val ///// ///// ///// 可以为负 ///// 减少后的值 //public double StringDecrement(string key, double val = 1) //{ // key = AddSysCustomKey(key); // return Do(db => db.StringDecrement(key, val)); //} //#endregion 同步方法 //#region 异步方法 ///// ///// 保存单个key value ///// ///// Redis Key ///// 保存的值 ///// 过期时间 ///// //public async Task StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?)) //{ // key = AddSysCustomKey(key); // return await Do(db => db.StringSetAsync(key, value, expiry)); //} ///// ///// 保存多个key value ///// ///// 键值对 ///// //public async Task StringSetAsync(List> keyValues) //{ // List> newkeyValues = // keyValues.Select(p => new KeyValuePair(AddSysCustomKey(p.Key), p.Value)).ToList(); // return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); //} ///// ///// 保存一个对象 ///// ///// ///// ///// ///// ///// //public async Task StringSetAsync(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) //{ // key = AddSysCustomKey(key); // string json = ConvertJson(obj); // return await Do(db => db.StringSetAsync(key, json, expiry)); //} ///// ///// 获取单个key的值 ///// ///// Redis Key ///// //public async Task StringGetAsync(string key) //{ // key = AddSysCustomKey(key); // return await Do(db => db.StringGetAsync(key)); //} ///// ///// 获取多个Key ///// ///// Redis Key集合 ///// //public async Task StringGetAsync(List listKey) //{ // List newKeys = listKey.Select(AddSysCustomKey).ToList(); // return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys))); //} ///// ///// 获取一个key的对象 ///// ///// ///// ///// //public async Task StringGetAsync(string key) //{ // key = AddSysCustomKey(key); // string result = await Do(db => db.StringGetAsync(key)); // return ConvertObj(result); //} ///// ///// 为数字增长val ///// ///// ///// 可以为负 ///// 增长后的值 //public async Task StringIncrementAsync(string key, double val = 1) //{ // key = AddSysCustomKey(key); // return await Do(db => db.StringIncrementAsync(key, val)); //} ///// ///// 为数字减少val ///// ///// ///// 可以为负 ///// 减少后的值 //public async Task StringDecrementAsync(string key, double val = 1) //{ // key = AddSysCustomKey(key); // return await Do(db => db.StringDecrementAsync(key, val)); //} //#endregion 异步方法 //#endregion String //#region Hash //#region 同步方法 /// /// 判断某个数据是否已经被缓存 /// /// /// /// public bool HashExists(string key, string dataKey) { if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(dataKey)) return false; key = AddSysCustomKey(key); return Do(db => db.HashExists(key, dataKey)); } ///// ///// 存储数据到hash表 ///// ///// ///// ///// ///// ///// //public bool HashSet(string key, string dataKey, T t) //{ // key = AddSysCustomKey(key); // return Do(db => // { // string json = ConvertJson(t); // return db.HashSet(key, dataKey, json); // }); //} /// /// 移除hash中的某值 /// /// /// /// public bool HashDelete(string key, string dataKey) { if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(dataKey)) return false; key = AddSysCustomKey(key); return Do(db => db.HashDelete(key, dataKey)); } ///// ///// 移除hash中的多个值 ///// ///// ///// ///// //public long HashDelete(string key, List dataKeys) //{ // key = AddSysCustomKey(key); // //List dataKeys1 = new List() {"1","2"}; // return Do(db => db.HashDelete(key, dataKeys.ToArray())); //} /// /// 从hash表获取数据 /// /// /// /// /// public T HashGet(string key, string dataKey) { if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(dataKey)) return default(T); key = AddSysCustomKey(key); return Do(db => { string value = db.HashGet(key, dataKey); if (!string.IsNullOrEmpty(value)) return ConvertObj(value); else return default(T); }); } ///// ///// 为数字增长val ///// ///// ///// ///// 可以为负 ///// 增长后的值 //public double HashIncrement(string key, string dataKey, double val = 1) //{ // key = AddSysCustomKey(key); // return Do(db => db.HashIncrement(key, dataKey, val)); //} ///// ///// 为数字减少val ///// ///// ///// ///// 可以为负 ///// 减少后的值 //public double HashDecrement(string key, string dataKey, double val = 1) //{ // key = AddSysCustomKey(key); // return Do(db => db.HashDecrement(key, dataKey, val)); //} ///// ///// 获取hashkey所有Redis key ///// ///// ///// ///// //public List HashKeys(string key) //{ // key = AddSysCustomKey(key); // return Do(db => // { // RedisValue[] values = db.HashKeys(key); // return ConvetList(values); // }); //} ///// ///// ///// ///// ///// ///// //public List HashValues(string key) //{ // var result = new List(); // key = AddSysCustomKey(key); // return Do(db => // { // HashEntry[] arr = db.HashGetAll(key); // foreach (var item in arr) // { // if (!item.Value.IsNullOrEmpty) // { // result.Add(JsonConvert.DeserializeObject(item.Value)); // } // } // return result; // }); //} public HashEntry[] HashValueAll(string key) { key = AddSysCustomKey(key); return Do(db => { HashEntry[] arr = db.HashGetAll(key); return arr; }); } //#endregion 同步方法 //#region 异步方法 ///// ///// 判断某个数据是否已经被缓存 ///// ///// ///// ///// //public async Task HashExistsAsync(string key, string dataKey) //{ // key = AddSysCustomKey(key); // return await Do(db => db.HashExistsAsync(key, dataKey)); //} ///// ///// 存储数据到hash表 ///// ///// ///// ///// ///// ///// //public async Task HashSetAsync(string key, string dataKey, T t) //{ // key = AddSysCustomKey(key); // return await Do(db => // { // string json = ConvertJson(t); // return db.HashSetAsync(key, dataKey, json); // }); //} ///// ///// 移除hash中的某值 ///// ///// ///// ///// //public async Task HashDeleteAsync(string key, string dataKey) //{ // key = AddSysCustomKey(key); // return await Do(db => db.HashDeleteAsync(key, dataKey)); //} ///// ///// 移除hash中的多个值 ///// ///// ///// ///// //public async Task HashDeleteAsync(string key, List dataKeys) //{ // key = AddSysCustomKey(key); // //List dataKeys1 = new List() {"1","2"}; // return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); //} ///// ///// 从hash表获取数据 ///// ///// ///// ///// ///// //public async Task HashGetAsync(string key, string dataKey) //{ // key = AddSysCustomKey(key); // string value = await Do(db => db.HashGetAsync(key, dataKey)); // return ConvertObj(value); //} ///// ///// 为数字增长val ///// ///// ///// ///// 可以为负 ///// 增长后的值 //public async Task HashIncrementAsync(string key, string dataKey, double val = 1) //{ // key = AddSysCustomKey(key); // return await Do(db => db.HashIncrementAsync(key, dataKey, val)); //} ///// ///// 为数字减少val ///// ///// ///// ///// 可以为负 ///// 减少后的值 //public async Task HashDecrementAsync(string key, string dataKey, double val = 1) //{ // key = AddSysCustomKey(key); // return await Do(db => db.HashDecrementAsync(key, dataKey, val)); //} ///// ///// 获取hashkey所有Redis key ///// ///// ///// ///// //public async Task> HashKeysAsync(string key) //{ // key = AddSysCustomKey(key); // RedisValue[] values = await Do(db => db.HashKeysAsync(key)); // return ConvetList(values); //} ///// ///// ///// ///// ///// ///// //public async Task> HashValuesAsync(string key) //{ // var result = new List(); // key = AddSysCustomKey(key); // HashEntry[] arr = await Do(db => db.HashGetAllAsync(key)); // foreach (var item in arr) // { // string values = item.Name; // if (!item.Value.IsNullOrEmpty) // { // result.Add(JsonConvert.DeserializeObject(item.Value)); // } // } // return result; //} ///// ///// ///// ///// ///// ///// //public async Task HashValueAllAsync(string key) //{ // key = AddSysCustomKey(key); // HashEntry[] arr = await Do(db => db.HashGetAllAsync(key)); // return arr; //} #endregion 异步方法 #endregion Hash //#region List //#region 同步方法 ///// ///// 移除指定ListId的内部List的值 ///// ///// ///// //public void ListRemove(string key, T value) //{ // key = AddSysCustomKey(key); // Do(db => db.ListRemove(key, ConvertJson(value))); //} ///// ///// 获取指定key的List ///// ///// ///// //public List ListRange(string key) //{ // key = AddSysCustomKey(key); // return Do(redis => // { // var values = redis.ListRange(key); // return ConvetList(values); // }); //} ///// ///// 入队 ///// ///// ///// //public void ListRightPush(string key, T value) //{ // key = AddSysCustomKey(key); // Do(db => db.ListRightPush(key, ConvertJson(value))); //} ///// ///// 出队 ///// ///// ///// ///// //public T ListRightPop(string key) //{ // key = AddSysCustomKey(key); // return Do(db => // { // var value = db.ListRightPop(key); // return ConvertObj(value); // }); //} ///// ///// 入栈 ///// ///// ///// ///// //public void ListLeftPush(string key, T value) //{ // key = AddSysCustomKey(key); // Do(db => db.ListLeftPush(key, ConvertJson(value))); //} ///// ///// 出栈 ///// ///// ///// ///// //public T ListLeftPop(string key) //{ // key = AddSysCustomKey(key); // return Do(db => // { // var value = db.ListLeftPop(key); // return ConvertObj(value); // }); //} ///// ///// 获取集合中的数量 ///// ///// ///// //public long ListLength(string key) //{ // key = AddSysCustomKey(key); // return Do(redis => redis.ListLength(key)); //} //#endregion 同步方法 //#region 异步方法 ///// ///// 移除指定ListId的内部List的值 ///// ///// ///// //public async Task ListRemoveAsync(string key, T value) //{ // key = AddSysCustomKey(key); // return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); //} ///// ///// 获取指定key的List ///// ///// ///// //public async Task> ListRangeAsync(string key) //{ // key = AddSysCustomKey(key); // var values = await Do(redis => redis.ListRangeAsync(key)); // return ConvetList(values); //} ///// ///// 入队 ///// ///// ///// //public async Task ListRightPushAsync(string key, T value) //{ // key = AddSysCustomKey(key); // return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); //} ///// ///// 出队 ///// ///// ///// ///// //public async Task ListRightPopAsync(string key) //{ // key = AddSysCustomKey(key); // var value = await Do(db => db.ListRightPopAsync(key)); // return ConvertObj(value); //} ///// ///// 入栈 ///// ///// ///// ///// //public async Task ListLeftPushAsync(string key, T value) //{ // key = AddSysCustomKey(key); // return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); //} ///// ///// 出栈 ///// ///// ///// ///// //public async Task ListLeftPopAsync(string key) //{ // key = AddSysCustomKey(key); // var value = await Do(db => db.ListLeftPopAsync(key)); // return ConvertObj(value); //} ///// ///// 获取集合中的数量 ///// ///// ///// //public async Task ListLengthAsync(string key) //{ // key = AddSysCustomKey(key); // return await Do(redis => redis.ListLengthAsync(key)); //} //#endregion 异步方法 //#endregion List //#region SortedSet 有序集合 //#region 同步方法 ///// ///// 添加 ///// ///// ///// ///// //public bool SortedSetAdd(string key, T value, double score) //{ // key = AddSysCustomKey(key); // return Do(redis => redis.SortedSetAdd(key, ConvertJson(value), score)); //} ///// ///// 添加???????? ///// ///// ///// ///// //public double SortedSetIncrement(string key, T value, double score) //{ // key = AddSysCustomKey(key); // return Do(redis => redis.SortedSetIncrement(key, ConvertJson(value), score)); //} //public bool SortedSetAdd(string key, SortedSetEntry[] values) //{ // key = AddSysCustomKey(key); // Do(redis => redis.SortedSetAdd(key, values, CommandFlags.None)); // return true; //} //public async Task SortedSetAddAsync(string key, SortedSetEntry[] values) //{ // key = AddSysCustomKey(key); // await Do(redis => redis.SortedSetAddAsync(key, values)); // return true; //} ///// ///// 删除 ///// ///// ///// //public bool SortedSetRemove(string key, T value) //{ // key = AddSysCustomKey(key); // return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); //} ///// ///// 获取全部 ///// ///// ///// //public List SortedSetRangeByRank(string key) //{ // key = AddSysCustomKey(key); // return Do(redis => // { // var values = redis.SortedSetRangeByRank(key); // return ConvetList(values); // }); //} ///// ///// 获取全部 ///// ///// ///// //public RedisValue[] SortedSetRangeByRank(string key) //{ // key = AddSysCustomKey(key); // return Do(redis => // { // return redis.SortedSetRangeByRank(key); // }); //} //public IEnumerable SortedSetScan(string key, RedisValue pattern = default) //{ // key = AddSysCustomKey(key); // return Do(redis => // { // return redis.SortedSetScan(key, pattern); // }); //} //public async Task> SortedSetScanAsync(string key, RedisValue pattern = default) //{ // key = AddSysCustomKey(key); // return Do(redis => // { // return redis.SortedSetScanAsync(key,pattern); // }); //} ///// ///// 获取集合中的数量 ///// ///// ///// //public long SortedSetLength(string key) //{ // key = AddSysCustomKey(key); // return Do(redis => redis.SortedSetLength(key)); //} //#endregion 同步方法 //#region 异步方法 ///// ///// 添加 ///// ///// ///// ///// //public async Task SortedSetAddAsync(string key, T value, double score) //{ // key = AddSysCustomKey(key); // return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson(value), score)); //} ///// ///// 删除 ///// ///// ///// //public async Task SortedSetRemoveAsync(string key, T value) //{ // key = AddSysCustomKey(key); // return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); //} ///// ///// 获取全部 ///// ///// ///// //public async Task> SortedSetRangeByRankAsync(string key) //{ // key = AddSysCustomKey(key); // var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); // return ConvetList(values); //} ///// ///// 获取集合中的数量 ///// ///// ///// //public async Task SortedSetLengthAsync(string key) //{ // key = AddSysCustomKey(key); // return await Do(redis => redis.SortedSetLengthAsync(key)); //} //#endregion 异步方法 //#endregion SortedSet 有序集合 //#region key ///// ///// 删除单个key ///// ///// redis key ///// 是否删除成功 //public bool KeyDelete(string key) //{ // key = AddSysCustomKey(key); // return Do(db => db.KeyDelete(key)); //} //public async Task KeyDeleteAsync(string key) //{ // key = AddSysCustomKey(key); // return await Do(db => db.KeyDeleteAsync(key)); //} ///// ///// 删除多个key ///// ///// rediskey ///// 成功删除的个数 //public long KeyDelete(List keys) //{ // List newKeys = keys.Select(AddSysCustomKey).ToList(); // return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys))); //} ///// ///// 判断key是否存储 ///// ///// redis key ///// //public bool KeyExists(string key) //{ // key = AddSysCustomKey(key); // return Do(db => db.KeyExists(key)); //} ///// ///// 重新命名key ///// ///// 就的redis key ///// 新的redis key ///// //public bool KeyRename(string key, string newKey) //{ // key = AddSysCustomKey(key); // return Do(db => db.KeyRename(key, newKey)); //} ///// ///// 设置Key的时间 ///// ///// redis key ///// ///// //public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) //{ // key = AddSysCustomKey(key); // return Do(db => db.KeyExpire(key, expiry)); //} /// /// 获取所有KEY /// /// public List GetAllCacheKeys() { try { var result = new List(); var endpoints = _conn.GetEndPoints(true); foreach (var endpoint in endpoints) { var server = _conn.GetServer(endpoint); result.AddRange(server.Keys(DbNum).Select(x => x.ToString())); } return result.Distinct().ToList(); } catch { return null; } } ///// ///// 获取所有KEY-Value ///// ///// //public IDictionary GetAll() //{ // try // { // var result = new Dictionary(); // IDatabase idb = _conn.GetDatabase(DbNum); // var endpoints = _conn.GetEndPoints(true); // foreach (var endpoint in endpoints) // { // var server = _conn.GetServer(endpoint); // foreach (var item in server.Keys(DbNum)) // { // result.Add(item.ToString(), idb.StringGet(item.ToString())); // } // } // return result; // } // catch // { // return null; // } //} //#endregion key //#region 发布订阅 ///// ///// Redis发布订阅 订阅 ///// ///// ///// //public void Subscribe(string subChannel, Action handler = null) //{ // ISubscriber sub = _conn.GetSubscriber(); // sub.Subscribe(subChannel, (channel, message) => // { // if (handler == null) // { // Console.WriteLine(subChannel + " 订阅收到消息:" + message); // } // else // { // handler(channel, message); // } // }); //} ///// ///// Redis发布订阅 发布 ///// ///// ///// ///// ///// //public long Publish(string channel, T msg) //{ // ISubscriber sub = _conn.GetSubscriber(); // return sub.Publish(channel, ConvertJson(msg)); //} ///// ///// Redis发布订阅 取消订阅 ///// ///// //public void Unsubscribe(string channel) //{ // ISubscriber sub = _conn.GetSubscriber(); // sub.Unsubscribe(channel); //} ///// ///// Redis发布订阅 取消全部订阅 ///// //public void UnsubscribeAll() //{ // ISubscriber sub = _conn.GetSubscriber(); // sub.UnsubscribeAll(); //} //#endregion 发布订阅 #region 其他 /// /// 获取list的redis /// /// /// public List GetListKeys(Guid orgid) { return this.HashValueAll("opt_list_" + orgid).ToList(); } /// /// 删除list中的某张表数据 /// /// /// /// public bool DeleteListKeys(Guid orgid, string name) { if (this.HashExists("opt_list_" + orgid, name)) { return this.HashDelete("opt_list_" + orgid, name); } return true; } /// /// 是否存在 /// /// /// /// public bool ExistsListKeys(Guid orgid, string name) { return this.HashExists("opt_list_" + orgid, name); } /// /// 获取list中表的rediskey /// /// /// /// public string GetListKey(Guid orgid, string name) { return this.HashGet("opt_list_" + orgid, name); } public ITransaction CreateTransaction() { return GetDatabase().CreateTransaction(); } public IDatabase GetDatabase() { return _conn.GetDatabase(DbNum); } public IServer GetServer(string hostAndPort) { return _conn.GetServer(hostAndPort); } #endregion 其他 #region 辅助方法 private string AddSysCustomKey(string oldKey) { var prefixKey = RedisConfig.SysCustomKey; return prefixKey + oldKey; } private T Do(Func func) { try { var database = _conn.GetDatabase(DbNum); return func(database); } catch (Exception ex) { Console.WriteLine($"reids.do:{ex.Message}"); return default(T); } } public string ConvertJson(T value) { string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value, _jsonSetting); return result; } //private T ConvertObj(RedisValue value) //{ // if (value.HasValue) // { // // return SerializerJson.DeserializeObject(value); // return Newtonsoft.Json.JsonConvert.DeserializeObject(value); // //return SerializerJson.DeserializeObject(value); // } // return default(T); //} private T ConvertObj(RedisValue value) { if (typeof(T).Name.Equals(typeof(string).Name)) { return JsonConvert.DeserializeObject($"'{value}'"); } else { T t = JsonConvert.DeserializeObject(value); if (t == null) { Console.WriteLine($"reids.ConvertObj.t:{null}"); } return t; } } private List ConvetList(RedisValue[] values) { List result = new List(); foreach (var item in values) { var model = ConvertObj(item); result.Add(model); } return result; } private RedisKey[] ConvertRedisKeys(List redisKeys) { return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); } #endregion 辅助方法 } }