using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace learun.cache { /// /// 版 本 EasyCode EC管理后台 /// Copyright (c) 2019-present EC管理有限公司 /// 创建人:tobin /// 日 期:2019.09.09 /// 描 述:Redis缓存 /// public class RedisCache { private int DbNum { get; set; } /// /// Redis连接 /// private readonly ConnectionMultiplexer _conn; /// /// 设置自定义键 /// public string CustomKey; #region 构造函数 /// /// 构造函数 /// /// public RedisCache(int dbNum = 0) : this(dbNum, null) { } /// /// 构造函数 /// /// /// public RedisCache(int dbNum, string readWriteHosts) { DbNum = dbNum; _conn = string.IsNullOrWhiteSpace(readWriteHosts) ? RedisConnectionHelp.Instance : RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts); } #endregion 构造函数 #region String #region 同步方法 /// /// 保存单个key value /// /// Redis Key /// 保存的值 /// 过期时间 /// public bool StringSet(string key, string value, TimeSpan? expiry = default) { 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) { key = AddSysCustomKey(key); string json = ConvertJson(obj); return Do(db => db.StringSet(key, json, expiry)); } /// /// 获取单个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) { 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) { 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) { 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) { 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 string HashGet(string key, string dataKey) { key = AddSysCustomKey(key); return Do(db => { string value = db.HashGet(key, dataKey); return value; }); } /// /// 从hash表获取Model /// /// /// /// /// public T HashGet(string key, string dataKey) { key = AddSysCustomKey(key); return Do(db => { string value = db.HashGet(key, dataKey); return ConvertObj(value); }); } /// /// 从hash表获取List /// /// /// /// public IList HashGetList(string key) { key = AddSysCustomKey(key); return Do(db => { RedisValue[] values = db.HashValues(key); return ConvetList(values); }); } /// /// 为数字增长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); }); } #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 HashGeAsync(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); } #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 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 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)); } /// /// 删除单个key /// /// /// public Task KeyDeleteAsync(string key) { key = AddSysCustomKey(key); return 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) { key = AddSysCustomKey(key); return Do(db => db.KeyExpire(key, expiry)); } #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); } }); //写法二 sub.Subscribe(subChannel, new Action((channel, message) => { Console.WriteLine(subChannel + " 订阅收到消息:" + message); })); //写法三 sub.Subscribe(subChannel, new Action(GetMessage)); } /// /// 获取订阅消息(写法三) /// /// /// private static void GetMessage(RedisChannel channel, RedisValue message) { Console.WriteLine(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 其他 /// /// 获取事物 /// /// public ITransaction CreateTransaction() { return GetDatabase().CreateTransaction(); } /// /// 获取批处理(管道模式) /// /// public IBatch CreateBatch() { return GetDatabase().CreateBatch(); } /// /// /// /// public IDatabase GetDatabase() { return _conn.GetDatabase(DbNum); } /// /// /// /// /// public IServer GetServer(string hostAndPort) { return _conn.GetServer(hostAndPort); } /// /// /// /// public void FlushDatabase(int dbNum) { var list = _conn.GetEndPoints(); foreach (var item in list) { _conn.GetServer(item).FlushDatabase(dbNum); } } /// /// /// /// /// public async Task FlushDatabaseAsync(int dbNum) { var list = _conn.GetEndPoints(); foreach (var item in list) { await _conn.GetServer(item).FlushDatabaseAsync(dbNum); } } /// /// 设置前缀 /// /// 自定义键 public void SetSysCustomKey(string customKey) { CustomKey = customKey; } #endregion 其他 #region 辅助方法 /// /// 添加自定义键 /// /// /// private string AddSysCustomKey(string oldKey) { var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey; return prefixKey + oldKey; } private T Do(Func func) { var database = _conn.GetDatabase(DbNum); return func(database); } /// /// 序列化 /// /// /// 值 /// private string ConvertJson(T value) { string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); return result; } /// /// 反序列化 /// /// /// /// private T ConvertObj(RedisValue value) { if (value.IsNullOrEmpty) { return default; } if (typeof(T) == typeof(string)) { return (T)Convert.ChangeType(value, typeof(T)); } return JsonConvert.DeserializeObject(value); } private List ConvetList(RedisValue[] values) { List result = new List(); foreach (var item in values) { if (!item.IsNullOrEmpty) { var model = ConvertObj(item); result.Add(model); } } return result; } private RedisKey[] ConvertRedisKeys(List redisKeys) { return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); } #endregion 辅助方法 } }