KxsRedisDbconn.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using Library;
  5. namespace MySystem
  6. {
  7. public class KxsRedisDbconn
  8. {
  9. public readonly static KxsRedisDbconn Instance = new KxsRedisDbconn();
  10. public static CSRedis.CSRedisClient csredis;
  11. private KxsRedisDbconn()
  12. {
  13. }
  14. #region 设置单个字段
  15. public bool Set(string key, object value)
  16. {
  17. return csredis.Set(key, value);
  18. // return false;
  19. }
  20. #endregion
  21. #region 整数累加
  22. public long AddInt(string key, long value = 1)
  23. {
  24. return csredis.IncrBy(key, value);
  25. // return 0;
  26. }
  27. #endregion
  28. #region 数字累加
  29. public decimal AddNumber(string key, decimal value = 1)
  30. {
  31. return csredis.IncrByFloat(key, value);
  32. // return 0;
  33. }
  34. #endregion
  35. #region 获取单个字段
  36. public T Get<T>(string key)
  37. {
  38. return csredis.Get<T>(key);
  39. }
  40. #endregion
  41. #region 设置散列字段
  42. public bool HSet(string key, string field, object value)
  43. {
  44. return csredis.HSet(key, field, value);
  45. // return false;
  46. }
  47. #endregion
  48. #region 散列整数累加
  49. public long HAddInt(string key, string field, long value = 1)
  50. {
  51. return csredis.HIncrBy(key, field, value);
  52. // return 0;
  53. }
  54. #endregion
  55. #region 散列数字累加
  56. public decimal HAddNumber(string key, string field, decimal value = 1)
  57. {
  58. return csredis.HIncrByFloat(key, field, value);
  59. // return 0;
  60. }
  61. #endregion
  62. #region 获取散列元素
  63. public T HGet<T>(string key, string field)
  64. {
  65. return csredis.HGet<T>(key, field);
  66. }
  67. #endregion
  68. #region 获取散列所有元素
  69. public Dictionary<string, T> HGetAll<T>(string key)
  70. {
  71. return csredis.HGetAll<T>(key);
  72. }
  73. #endregion
  74. #region 添加列表对象
  75. public long AddList(string key, object value)
  76. {
  77. return csredis.LPush(key, value);
  78. // return 0;
  79. }
  80. public long AddList(string key, object[] value)
  81. {
  82. return csredis.LPush(key, value);
  83. // return 0;
  84. }
  85. public T RPop<T>(string key)
  86. {
  87. return csredis.RPop<T>(key);
  88. }
  89. #endregion
  90. #region 添加集合对象
  91. public long SAdd(string key, object value)
  92. {
  93. return csredis.SAdd(key, value);
  94. // return 0;
  95. }
  96. public long SAdd(string key, object[] value)
  97. {
  98. return csredis.SAdd(key, value);
  99. // return 0;
  100. }
  101. #endregion
  102. #region 获取集合对象
  103. public T[] SGetList<T>(string key)
  104. {
  105. return csredis.SMembers<T>(key);
  106. }
  107. #endregion
  108. #region 修改列表对象
  109. public bool SetList(string key, int index, object value)
  110. {
  111. long itemindex = csredis.LLen(key) - index - 1;
  112. return csredis.LSet(key, itemindex, value);
  113. // return false;
  114. }
  115. #endregion
  116. #region 获取列表
  117. public List<T> GetList<T>(string key, int pageNum = 1, int pageSize = 10)
  118. {
  119. int start = (pageNum - 1) * pageSize;
  120. int end = start + pageSize - 1;
  121. string[] list = csredis.LRange(key, start, end);
  122. List<T> lists = new List<T>();
  123. foreach (string record in list)
  124. {
  125. lists.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<T>(record));
  126. }
  127. return lists;
  128. }
  129. #endregion
  130. #region 移除列表
  131. public long RemoveFromList(string key, object value, int count = 1)
  132. {
  133. return csredis.LRem(key, count, value);
  134. }
  135. #endregion
  136. #region 添加排序列表对象
  137. public long AddSort(string key, object value, decimal score)
  138. {
  139. return csredis.ZAdd(key, (score, value));
  140. // return 0;
  141. }
  142. #endregion
  143. #region 获取排序列表
  144. public List<T> GetSort<T>(string key, int pageNum = 1, int pageSize = 10)
  145. {
  146. int start = (pageNum - 1) * pageSize;
  147. int end = start + pageSize;
  148. string[] list = csredis.ZRangeByScore(key, start, end);
  149. List<T> lists = new List<T>();
  150. foreach (string record in list)
  151. {
  152. lists.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<T>(record));
  153. }
  154. return lists;
  155. }
  156. public List<T> GetSortDesc<T>(string key, int pageNum = 1, int pageSize = 10)
  157. {
  158. int start = (pageNum - 1) * pageSize;
  159. int end = start + pageSize;
  160. string[] list = csredis.ZRevRangeByScore(key, start, end);
  161. List<T> lists = new List<T>();
  162. foreach (string record in list)
  163. {
  164. lists.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<T>(record));
  165. }
  166. return lists;
  167. }
  168. #endregion
  169. public bool Remove(string key, long start, long end)
  170. {
  171. return csredis.LTrim(key, start, end);
  172. }
  173. public bool RemoveTop(string key, long count)
  174. {
  175. return RedisDbconn.Instance.Remove(key, count, RedisDbconn.Instance.Count(key) - 1); ;
  176. }
  177. public long Count(string key)
  178. {
  179. return csredis.LLen(key);
  180. }
  181. public void Clear(string pattern)
  182. {
  183. string[] keys = csredis.Keys(pattern);
  184. csredis.Del(keys);
  185. }
  186. public string[] GetKeys(string pattern)
  187. {
  188. string[] keys = csredis.Keys(pattern);
  189. return keys;
  190. }
  191. public void SetExpire(string key, int expire)
  192. {
  193. csredis.Expire(key, expire); //秒为单位
  194. }
  195. public bool Exists(string key)
  196. {
  197. return csredis.Exists(key);
  198. }
  199. public long AddRightList(string key, object value)
  200. {
  201. return csredis.RPush(key, value);
  202. // return 0;
  203. }
  204. /// <summary>
  205. /// 锁key
  206. /// </summary>
  207. private readonly string lockKey = "RedisLock";
  208. /// <summary>
  209. /// 锁的过期秒数
  210. /// </summary>
  211. private readonly int lockTime = 20;
  212. /// <summary>
  213. /// 续命线程取消令牌
  214. /// </summary>
  215. private CancellationTokenSource tokenSource = new CancellationTokenSource();
  216. /// <summary>
  217. /// 获取锁
  218. /// </summary>
  219. /// <param name="requestId">请求id保证释放锁时的客户端和加锁的客户端一致</param>
  220. /// <returns></returns>
  221. public bool GetLock(string requestId)
  222. {
  223. //设置key 设置过期时间20s
  224. // while (true)
  225. // {
  226. // //设置key Redis2.6.12以上版本,可以用set获取锁。set可以实现setnx和expire,这个是原子操作
  227. // if (csredis.Set(lockKey, requestId, lockTime, csredis.RedisExistence.Nx))
  228. // {
  229. // //设置成功后开启子线程为key续命
  230. // CreateThredXm();
  231. // return true;
  232. // }
  233. // }
  234. return true;
  235. }
  236. /// <summary>
  237. /// 为锁续命(防止业务操作时间大于锁自动释放时间,锁被自动释放掉)
  238. /// </summary>
  239. void CreateThredXm()
  240. {
  241. Task.Run(() =>
  242. {
  243. while (true)
  244. {
  245. Thread.Sleep(10);
  246. //外部取消 退出子线程
  247. if (tokenSource.IsCancellationRequested)
  248. {
  249. return;
  250. }
  251. //查询key还有多少秒释放
  252. var Seconds = csredis.PTtl(lockKey) / 1000;
  253. //key还剩1/3秒时重设过期时间
  254. if (Seconds < (lockTime / 3))
  255. {
  256. //小于5秒则自动 重设过期时间
  257. csredis.Expire(lockKey, lockTime);
  258. }
  259. }
  260. }, tokenSource.Token);
  261. }
  262. /// <summary>
  263. /// 释放锁操作
  264. /// </summary>
  265. /// <param name="requestId">请求id保证释放锁时的客户端和加锁的客户端一致</param>
  266. public void ReleaseLock(string requestId)
  267. {
  268. //这里使用Lua脚本保证原子性操作
  269. // string script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
  270. // "return redis.call('del', KEYS[1]) " +
  271. // "else return 0 end";
  272. // csredis.Eval(script, lockKey, requestId);
  273. // //取消续命线程
  274. // tokenSource.Cancel();
  275. }
  276. }
  277. }