using Common; using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; namespace KC.Cache.Redis { public class RedisHelper { #region 属性 /// <summary> /// 数据库编号 /// </summary> private int DbNum { get; } /// <summary> /// 连接 /// </summary> private readonly ConnectionMultiplexer _conn; #endregion #region 构造函数 /// <summary> /// 构造函数 /// </summary> /// <param name="dbNum">数据库编号</param> /// <param name="readWriteHosts">链接地址</param> public RedisHelper() { this.DbNum = ConfigHelper.GetValue("RedisDbNum").TryToInt32(); string readWriteHosts = ConfigHelper.GetValue("RedisExchangeHosts"); this._conn = ConnectionMultiplexer.Connect(readWriteHosts); } #endregion 构造函数 #region 方法 /// <summary> /// 单个string值存入 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiry"></param> /// <returns></returns> public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) { return Do(db => db.StringSet(key, value, expiry)); } /// <summary> /// 单个string值存入 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiry"></param> /// <returns></returns> public bool StringSet<T>(string key, T value, TimeSpan? expiry = default(TimeSpan?)) { return Do(db => db.StringSet(key, ConvertJson(value), expiry)); } /// <summary> /// 对象存储 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiry"></param> /// <returns></returns> public void ListSet<T>(string key, T value) { Do(db => db.ListRightPush(key, value.TryToJson())); } /// <summary> /// 删除单个key /// </summary> /// <param name="key">redis key</param> /// <returns>是否删除成功</returns> public bool KeyDelete(string key) { return Do(db => db.KeyDelete(key)); } /// <summary> /// 获取单个key的值 /// </summary> /// <param name="key">Redis Key</param> /// <returns></returns> public string StringGet(string key) { return Do(db => db.StringGet(key)); } /// <summary> /// 获取指定key的List /// </summary> /// <param name="key"></param> /// <returns></returns> public List<T> ListGet<T>(string key) { return Do(redis => { try { var values = redis.ListRange(key); return ConvetList<T>(values); } catch (Exception) { return new List<T>(); } }); } /// <summary> /// 获取所有key /// </summary> /// <returns></returns> public List<string> GetAllKeys() { var res = Do(db => { EndPoint[] endpoints = _conn.GetEndPoints(); List<string> keyList = new List<string>(); foreach (EndPoint ep in endpoints) { var server = _conn.GetServer(ep); var keys = server.Keys(DbNum, "*"); foreach (var item in keys) { keyList.Add((string)item); } }; return keyList; }); return res; } /// <summary> /// 获取指定key的object /// </summary> /// <param name="key"></param> /// <returns></returns> public T ListRangeObj<T>(string key) {; return Do(redis => { try { var values = redis.ListRange(key); var content = values.Count() > 0 ? values[0] : new RedisValue(); return ConvertObj<T>(content); } catch (Exception) { Thread.Sleep(1000); var values = redis.ListRange(key); var content = values.Count() > 0 ? values[0] : new RedisValue(); return ConvertObj<T>(content); } }); } /// <summary> /// 判断key是否存储 /// </summary> /// <param name="key">redis key</param> /// <returns></returns> public bool KeyExists(string key) { return Do(db => db.KeyExists(key)); } /// <summary> /// 执行操作 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="func"></param> /// <returns></returns> private T Do<T>(Func<IDatabase, T> func) { var database = _conn.GetDatabase(DbNum); return func(database); } /// <summary> /// 设置Key的时间 /// </summary> /// <param name="key">redis key</param> /// <param name="expiry"></param> /// <returns></returns> public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) { return Do(db => db.KeyExpire(key, expiry)); } /// <summary> /// 删除多个key /// </summary> /// <param name="keys">rediskey</param> /// <returns>成功删除的个数</returns> public long KeyDelete(List<string> keys) { return Do(db => db.KeyDelete(ConvertRedisKeys(keys))); } #endregion #region 转换 /// <summary> /// 转换成集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="values"></param> /// <returns></returns> private List<T> ConvetList<T>(RedisValue[] values) { List<T> result = new List<T>(); //try //{ // //一个Key下面存了多个相同实体 // foreach (RedisValue value in values) // { // var model = ConvertObj<T>(value); // result.Add(model); // } //} //catch (Exception e) //{ //一个Key下面存的是一个集合 foreach (RedisValue value in values) { List<T> temp = JsonConvert.DeserializeObject<List<T>>(value); result = result.Concat(temp).ToList(); } // } return result; } /// <summary> /// 转换成Json字符串 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value"></param> /// <returns></returns> private string ConvertJson<T>(T value) { string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); return result; } /// <summary> /// 转换成对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="value"></param> /// <returns></returns> private T ConvertObj<T>(RedisValue value) { if (!value.IsNullOrEmpty) { var val = value.ToString(); try { if (!val.IsEmpty() && val.IsJson()) return JsonConvert.DeserializeObject<T>(val); return default(T); } catch (Exception ex) { throw; } } return default(T); } /// <summary> /// 批量转换成RedisKey /// </summary> /// <param name="redisKeys"></param> /// <returns></returns> private RedisKey[] ConvertRedisKeys(List<string> redisKeys) { return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); } #endregion } }