RedisHelper.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Masuit.Tools.Core.NoSQL;
  6. using Newtonsoft.Json;
  7. using StackExchange.Redis;
  8. namespace Masuit.Tools.NoSQL
  9. {
  10. /// <summary>
  11. /// Redis操作
  12. /// </summary>
  13. public class RedisHelper
  14. {
  15. private int DbNum { get; }
  16. private readonly ConnectionMultiplexer _conn;
  17. /// <summary>
  18. /// 自定义键
  19. /// </summary>
  20. public string CustomKey;
  21. /// <summary>
  22. /// 连接失败 , 如果重新连接成功你将不会收到这个通知
  23. /// </summary>
  24. public event EventHandler<ConnectionFailedEventArgs> ConnectionFailed;
  25. /// <summary>
  26. /// 重新建立连接之前的错误
  27. /// </summary>
  28. public event EventHandler<ConnectionFailedEventArgs> ConnectionRestored;
  29. /// <summary>
  30. /// 发生错误时
  31. /// </summary>
  32. public event EventHandler<RedisErrorEventArgs> ErrorMessage;
  33. /// <summary>
  34. /// 配置更改时
  35. /// </summary>
  36. public event EventHandler<EndPointEventArgs> ConfigurationChanged;
  37. /// <summary>
  38. /// 更改集群时
  39. /// </summary>
  40. public event EventHandler<HashSlotMovedEventArgs> HashSlotMoved;
  41. /// <summary>
  42. /// redis类库错误时
  43. /// </summary>
  44. public event EventHandler<InternalErrorEventArgs> InternalError;
  45. #region 构造函数
  46. /// <summary>
  47. /// 构造函数,使用该构造函数需要先在config中配置链接字符串,连接字符串在config配置文件中的ConnectionStrings节下配置,name固定为RedisHosts,值的格式:127.0.0.1:6379,allowadmin=true,若未正确配置,将按默认值“127.0.0.1:6379,allowadmin=true”进行操作,如:<br/>
  48. /// &lt;connectionStrings&gt;<br/>
  49. /// &lt;add name = "RedisHosts" connectionString="127.0.0.1:6379,allowadmin=true"/&gt;<br/>
  50. /// &lt;/connectionStrings&gt;
  51. /// </summary>
  52. /// <param name="dbNum">数据库编号</param>
  53. public RedisHelper(int dbNum = 0) : this(dbNum, null)
  54. {
  55. }
  56. /// <summary>
  57. /// 构造函数
  58. /// </summary>
  59. /// <param name="dbNum">数据库的编号</param>
  60. /// <param name="readWriteHosts">Redis服务器连接字符串,格式:127.0.0.1:6379,allowadmin=true</param>
  61. public RedisHelper(int dbNum = 0, string readWriteHosts = "127.0.0.1:6379,allowadmin=true")
  62. {
  63. DbNum = dbNum;
  64. _conn = string.IsNullOrWhiteSpace(readWriteHosts) ? RedisConnectionManager.Instance : RedisConnectionManager.GetConnectionMultiplexer(readWriteHosts);
  65. _conn.ConfigurationChanged += ConfigurationChanged;
  66. _conn.ConnectionFailed += ConnectionFailed;
  67. _conn.ConnectionRestored += ConnectionRestored;
  68. _conn.ErrorMessage += ErrorMessage;
  69. _conn.HashSlotMoved += HashSlotMoved;
  70. _conn.InternalError += InternalError;
  71. }
  72. /// <summary>
  73. /// 从对象池获取默认实例
  74. /// </summary>
  75. /// <param name="db">数据库的编号</param>
  76. /// <returns></returns>
  77. public static RedisHelper GetInstance(int db = 0)
  78. {
  79. return new RedisHelper(db);
  80. }
  81. /// <summary>
  82. /// 从对象池获取默认实例
  83. /// </summary>
  84. /// <param name="conn">Redis服务器连接字符串,格式:127.0.0.1:6379,allowadmin=true</param>
  85. /// <param name="db">数据库的编号</param>
  86. /// <returns></returns>
  87. public static RedisHelper GetInstance(string conn = "127.0.0.1:6379,allowadmin=true", int db = 0)
  88. {
  89. return new RedisHelper(db, conn);
  90. }
  91. #endregion 构造函数
  92. #region String
  93. #region 同步方法
  94. /// <summary>
  95. /// 保存单个key value
  96. /// </summary>
  97. /// <param name="key">Redis Key</param>
  98. /// <param name="value">保存的值</param>
  99. /// <param name="expiry">过期时间</param>
  100. /// <returns>是否保存成功</returns>
  101. public bool SetString(string key, string value, TimeSpan? expiry = default(TimeSpan?))
  102. {
  103. key = AddSysCustomKey(key);
  104. return Do(db => db.StringSet(key, value, expiry));
  105. }
  106. /// <summary>
  107. /// 保存多个key value
  108. /// </summary>
  109. /// <param name="keyValues">键值对</param>
  110. /// <returns>是否保存成功</returns>
  111. public bool SetString(List<KeyValuePair<RedisKey, RedisValue>> keyValues)
  112. {
  113. List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =
  114. keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();
  115. return Do(db => db.StringSet(newkeyValues.ToArray()));
  116. }
  117. /// <summary>
  118. /// 保存一个对象
  119. /// </summary>
  120. /// <typeparam name="T">对象类型</typeparam>
  121. /// <param name="key">键</param>
  122. /// <param name="obj">值</param>
  123. /// <param name="expiry">过期时间</param>
  124. /// <returns>是否保存成功</returns>
  125. public bool SetString<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
  126. {
  127. key = AddSysCustomKey(key);
  128. string json = ConvertJson(obj);
  129. return Do(db => db.StringSet(key, json, expiry));
  130. }
  131. /// <summary>
  132. /// 获取单个key的值
  133. /// </summary>
  134. /// <param name="key">键</param>
  135. /// <returns>值</returns>
  136. public string GetString(string key)
  137. {
  138. if (KeyExists(key))
  139. {
  140. key = AddSysCustomKey(key);
  141. return Do(db => db.StringGet(key));
  142. }
  143. return string.Empty;
  144. }
  145. /// <summary>
  146. /// 获取多个Key
  147. /// </summary>
  148. /// <param name="listKey">键集合</param>
  149. /// <returns>值集合</returns>
  150. public RedisValue[] GetString(List<string> listKey)
  151. {
  152. List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
  153. return Do(db => db.StringGet(ConvertRedisKeys(newKeys)));
  154. }
  155. /// <summary>
  156. /// 获取一个key的对象
  157. /// </summary>
  158. /// <typeparam name="T">数据类型</typeparam>
  159. /// <param name="key">键</param>
  160. /// <returns>实例对象</returns>
  161. public T GetString<T>(string key)
  162. {
  163. if (KeyExists(key))
  164. {
  165. key = AddSysCustomKey(key);
  166. return Do(db => ConvertObj<T>(db.StringGet(key)));
  167. }
  168. return default(T);
  169. }
  170. /// <summary>
  171. /// 为数字增长val
  172. /// </summary>
  173. /// <param name="key">键</param>
  174. /// <param name="val">可以为负</param>
  175. /// <returns>增长后的值</returns>
  176. public double StringIncrement(string key, double val = 1)
  177. {
  178. key = AddSysCustomKey(key);
  179. return Do(db => db.StringIncrement(key, val));
  180. }
  181. /// <summary>
  182. /// 为数字减少val
  183. /// </summary>
  184. /// <param name="key">键</param>
  185. /// <param name="val">可以为负</param>
  186. /// <returns>减少后的值</returns>
  187. public double StringDecrement(string key, double val = 1)
  188. {
  189. key = AddSysCustomKey(key);
  190. return Do(db => db.StringDecrement(key, val));
  191. }
  192. #endregion 同步方法
  193. #region 异步方法
  194. /// <summary>
  195. /// 保存单个key value
  196. /// </summary>
  197. /// <param name="key">Redis Key</param>
  198. /// <param name="value">保存的值</param>
  199. /// <param name="expiry">过期时间</param>
  200. /// <returns>是否保存成功</returns>
  201. public async Task<bool> SetStringAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?))
  202. {
  203. key = AddSysCustomKey(key);
  204. return await Do(db => db.StringSetAsync(key, value, expiry));
  205. }
  206. /// <summary>
  207. /// 保存多个key value
  208. /// </summary>
  209. /// <param name="keyValues">键值对</param>
  210. /// <returns>是否保存成功</returns>
  211. public async Task<bool> SetStringAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues)
  212. {
  213. List<KeyValuePair<RedisKey, RedisValue>> newkeyValues =
  214. keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList();
  215. return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));
  216. }
  217. /// <summary>
  218. /// 保存一个对象
  219. /// </summary>
  220. /// <typeparam name="T">数据类型</typeparam>
  221. /// <param name="key">键</param>
  222. /// <param name="obj">需要被缓存的对象</param>
  223. /// <param name="expiry">过期时间</param>
  224. /// <returns>是否保存成功</returns>
  225. public async Task<bool> SetStringAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
  226. {
  227. key = AddSysCustomKey(key);
  228. string json = ConvertJson(obj);
  229. return await Do(db => db.StringSetAsync(key, json, expiry));
  230. }
  231. /// <summary>
  232. /// 获取单个key的值
  233. /// </summary>
  234. /// <param name="key">键</param>
  235. /// <returns>值</returns>
  236. public async Task<string> GetStringAsync(string key)
  237. {
  238. if (KeyExists(key))
  239. {
  240. key = AddSysCustomKey(key);
  241. return await Do(db => db.StringGetAsync(key));
  242. }
  243. return string.Empty;
  244. }
  245. /// <summary>
  246. /// 获取多个Key
  247. /// </summary>
  248. /// <param name="listKey">键集合</param>
  249. /// <returns>值集合</returns>
  250. public Task<RedisValue[]> GetStringAsync(List<string> listKey)
  251. {
  252. List<string> newKeys = listKey.Select(AddSysCustomKey).ToList();
  253. return Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys)));
  254. }
  255. /// <summary>
  256. /// 获取一个key的对象
  257. /// </summary>
  258. /// <typeparam name="T">数据类型</typeparam>
  259. /// <param name="key">键</param>
  260. /// <returns>实例对象</returns>
  261. public async Task<T> GetStringAsync<T>(string key)
  262. {
  263. if (KeyExists(key))
  264. {
  265. key = AddSysCustomKey(key);
  266. string result = await Do(db => db.StringGetAsync(key));
  267. return ConvertObj<T>(result);
  268. }
  269. return default(T);
  270. }
  271. /// <summary>
  272. /// 为数字增长val
  273. /// </summary>
  274. /// <param name="key">键</param>
  275. /// <param name="val">可以为负</param>
  276. /// <returns>增长后的值</returns>
  277. public Task<double> IncrementStringAsync(string key, double val = 1)
  278. {
  279. key = AddSysCustomKey(key);
  280. return Do(db => db.StringIncrementAsync(key, val));
  281. }
  282. /// <summary>
  283. /// 为数字减少val
  284. /// </summary>
  285. /// <param name="key">键</param>
  286. /// <param name="val">可以为负</param>
  287. /// <returns>减少后的值</returns>
  288. public Task<double> DecrementStringAsync(string key, double val = 1)
  289. {
  290. key = AddSysCustomKey(key);
  291. return Do(db => db.StringDecrementAsync(key, val));
  292. }
  293. #endregion 异步方法
  294. #endregion String
  295. #region Hash
  296. #region 同步方法
  297. /// <summary>
  298. /// 判断某个数据是否已经被缓存
  299. /// </summary>
  300. /// <param name="key">键</param>
  301. /// <param name="dataKey">对象的字段</param>
  302. /// <returns>是否缓存成功</returns>
  303. public bool HashExists(string key, string dataKey)
  304. {
  305. key = AddSysCustomKey(key);
  306. return Do(db => db.HashExists(key, dataKey));
  307. }
  308. /// <summary>
  309. /// 存储数据到hash表
  310. /// </summary>
  311. /// <typeparam name="T">数据类型</typeparam>
  312. /// <param name="key">键</param>
  313. /// <param name="dataKey">对象的字段</param>
  314. /// <param name="t">对象实例</param>
  315. /// <returns>是否存储成功</returns>
  316. public bool SetHash<T>(string key, string dataKey, T t)
  317. {
  318. key = AddSysCustomKey(key);
  319. return Do(db =>
  320. {
  321. string json = ConvertJson(t);
  322. return db.HashSet(key, dataKey, json);
  323. });
  324. }
  325. /// <summary>
  326. /// 移除hash中的某值
  327. /// </summary>
  328. /// <param name="key">键</param>
  329. /// <param name="dataKey">对象的字段</param>
  330. /// <returns>是否移除成功</returns>
  331. public bool DeleteHash(string key, string dataKey)
  332. {
  333. key = AddSysCustomKey(key);
  334. return Do(db => db.HashDelete(key, dataKey));
  335. }
  336. /// <summary>
  337. /// 移除hash中的多个值
  338. /// </summary>
  339. /// <param name="key">键</param>
  340. /// <param name="dataKeys">对象的字段集合</param>
  341. /// <returns>数量</returns>
  342. public long DeleteHash(string key, List<RedisValue> dataKeys)
  343. {
  344. key = AddSysCustomKey(key);
  345. //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"};
  346. return Do(db => db.HashDelete(key, dataKeys.ToArray()));
  347. }
  348. /// <summary>
  349. /// 从hash表获取数据
  350. /// </summary>
  351. /// <typeparam name="T">数据类型</typeparam>
  352. /// <param name="key">键</param>
  353. /// <param name="dataKey">对象的字段</param>
  354. /// <returns>对象实例</returns>
  355. public T GetHash<T>(string key, string dataKey)
  356. {
  357. if (KeyExists(key))
  358. {
  359. key = AddSysCustomKey(key);
  360. return Do(db =>
  361. {
  362. string value = db.HashGet(key, dataKey);
  363. return ConvertObj<T>(value);
  364. });
  365. }
  366. return default(T);
  367. }
  368. /// <summary>
  369. /// 为数字增长val
  370. /// </summary>
  371. /// <param name="key">键</param>
  372. /// <param name="dataKey">对象的字段</param>
  373. /// <param name="val">可以为负</param>
  374. /// <returns>增长后的值</returns>
  375. public double IncrementHash(string key, string dataKey, double val = 1)
  376. {
  377. key = AddSysCustomKey(key);
  378. return Do(db => db.HashIncrement(key, dataKey, val));
  379. }
  380. /// <summary>
  381. /// 为数字减少val
  382. /// </summary>
  383. /// <param name="key">键</param>
  384. /// <param name="dataKey">对象的字段</param>
  385. /// <param name="val">可以为负</param>
  386. /// <returns>减少后的值</returns>
  387. public double DecrementHash(string key, string dataKey, double val = 1)
  388. {
  389. key = AddSysCustomKey(key);
  390. return Do(db => db.HashDecrement(key, dataKey, val));
  391. }
  392. /// <summary>
  393. /// 获取hashkey所有Redis key
  394. /// </summary>
  395. /// <typeparam name="T">数据类型</typeparam>
  396. /// <param name="key">键</param>
  397. /// <returns>数据集合</returns>
  398. public List<T> HashKeys<T>(string key)
  399. {
  400. key = AddSysCustomKey(key);
  401. return Do(db =>
  402. {
  403. RedisValue[] values = db.HashKeys(key);
  404. return ConvetList<T>(values);
  405. });
  406. }
  407. #endregion 同步方法
  408. #region 异步方法
  409. /// <summary>
  410. /// 判断某个数据是否已经被缓存
  411. /// </summary>
  412. /// <param name="key">键</param>
  413. /// <param name="dataKey">对象的字段</param>
  414. /// <returns>是否缓存成功</returns>
  415. public Task<bool> ExistsHashAsync(string key, string dataKey)
  416. {
  417. key = AddSysCustomKey(key);
  418. return Do(db => db.HashExistsAsync(key, dataKey));
  419. }
  420. /// <summary>
  421. /// 存储数据到hash表
  422. /// </summary>
  423. /// <typeparam name="T">数据类型</typeparam>
  424. /// <param name="key">键</param>
  425. /// <param name="dataKey">对象的字段</param>
  426. /// <param name="t">对象实例</param>
  427. /// <returns>是否存储成功</returns>
  428. public Task<bool> SetHashAsync<T>(string key, string dataKey, T t)
  429. {
  430. key = AddSysCustomKey(key);
  431. return Do(db =>
  432. {
  433. string json = ConvertJson(t);
  434. return db.HashSetAsync(key, dataKey, json);
  435. });
  436. }
  437. /// <summary>
  438. /// 移除hash中的某值
  439. /// </summary>
  440. /// <param name="key">键</param>
  441. /// <param name="dataKey">对象的字段</param>
  442. /// <returns>是否移除成功</returns>
  443. public Task<bool> DeleteHashAsync(string key, string dataKey)
  444. {
  445. key = AddSysCustomKey(key);
  446. return Do(db => db.HashDeleteAsync(key, dataKey));
  447. }
  448. /// <summary>
  449. /// 移除hash中的多个值
  450. /// </summary>
  451. /// <param name="key">键</param>
  452. /// <param name="dataKeys">对象的字段集合</param>
  453. /// <returns>数量</returns>
  454. public Task<long> DeleteHashAsync(string key, List<RedisValue> dataKeys)
  455. {
  456. key = AddSysCustomKey(key);
  457. return Do(db => db.HashDeleteAsync(key, dataKeys.ToArray()));
  458. }
  459. /// <summary>
  460. /// 从hash表获取数据
  461. /// </summary>
  462. /// <typeparam name="T">数据类型</typeparam>
  463. /// <param name="key">键</param>
  464. /// <param name="dataKey">对象的字段</param>
  465. /// <returns>对象实例</returns>
  466. public async Task<T> GetHashAsync<T>(string key, string dataKey)
  467. {
  468. if (KeyExists(key))
  469. {
  470. key = AddSysCustomKey(key);
  471. string value = await Do(db => db.HashGetAsync(key, dataKey));
  472. return ConvertObj<T>(value);
  473. }
  474. return default(T);
  475. }
  476. /// <summary>
  477. /// 为数字增长val
  478. /// </summary>
  479. /// <param name="key">键</param>
  480. /// <param name="dataKey">对象的字段</param>
  481. /// <param name="val">可以为负</param>
  482. /// <returns>增长后的值</returns>
  483. public Task<double> IncrementHashAsync(string key, string dataKey, double val = 1)
  484. {
  485. key = AddSysCustomKey(key);
  486. return Do(db => db.HashIncrementAsync(key, dataKey, val));
  487. }
  488. /// <summary>
  489. /// 为数字减少val
  490. /// </summary>
  491. /// <param name="key">键</param>
  492. /// <param name="dataKey">对象的字段</param>
  493. /// <param name="val">可以为负</param>
  494. /// <returns>减少后的值</returns>
  495. public Task<double> DecrementHashAsync(string key, string dataKey, double val = 1)
  496. {
  497. key = AddSysCustomKey(key);
  498. return Do(db => db.HashDecrementAsync(key, dataKey, val));
  499. }
  500. /// <summary>
  501. /// 获取hashkey所有Redis key
  502. /// </summary>
  503. /// <typeparam name="T">数据类型</typeparam>
  504. /// <param name="key">键</param>
  505. /// <returns>数据集合</returns>
  506. public async Task<List<T>> HashKeysAsync<T>(string key)
  507. {
  508. key = AddSysCustomKey(key);
  509. RedisValue[] values = await Do(db => db.HashKeysAsync(key));
  510. return ConvetList<T>(values);
  511. }
  512. #endregion 异步方法
  513. #endregion Hash
  514. #region List
  515. #region 同步方法
  516. /// <summary>
  517. /// 移除指定ListId的内部List的值
  518. /// </summary>
  519. /// <typeparam name="T">数据类型</typeparam>
  520. /// <param name="key">键</param>
  521. /// <param name="value">值</param>
  522. public void RemoveList<T>(string key, T value)
  523. {
  524. key = AddSysCustomKey(key);
  525. Do(db => db.ListRemove(key, ConvertJson(value)));
  526. }
  527. /// <summary>
  528. /// 获取指定key的List
  529. /// </summary>
  530. /// <typeparam name="T">数据类型</typeparam>
  531. /// <param name="key">键</param>
  532. /// <returns>数据集</returns>
  533. public List<T> ListRange<T>(string key)
  534. {
  535. if (KeyExists(key))
  536. {
  537. key = AddSysCustomKey(key);
  538. return Do(redis =>
  539. {
  540. var values = redis.ListRange(key);
  541. return ConvetList<T>(values);
  542. });
  543. }
  544. return new List<T>();
  545. }
  546. /// <summary>
  547. /// 入队
  548. /// </summary>
  549. /// <typeparam name="T">数据类型</typeparam>
  550. /// <param name="key">键</param>
  551. /// <param name="value">值</param>
  552. public void ListRightPush<T>(string key, T value)
  553. {
  554. key = AddSysCustomKey(key);
  555. Do(db => db.ListRightPush(key, ConvertJson(value)));
  556. }
  557. /// <summary>
  558. /// 出队
  559. /// </summary>
  560. /// <typeparam name="T">数据类型</typeparam>
  561. /// <param name="key">键</param>
  562. /// <returns>值</returns>
  563. public T ListRightPop<T>(string key)
  564. {
  565. if (KeyExists(key))
  566. {
  567. key = AddSysCustomKey(key);
  568. return Do(db =>
  569. {
  570. var value = db.ListRightPop(key);
  571. return ConvertObj<T>(value);
  572. });
  573. }
  574. return default(T);
  575. }
  576. /// <summary>
  577. /// 入栈
  578. /// </summary>
  579. /// <typeparam name="T">数据类型</typeparam>
  580. /// <param name="key">键</param>
  581. /// <param name="value">值</param>
  582. public void ListLeftPush<T>(string key, T value)
  583. {
  584. key = AddSysCustomKey(key);
  585. Do(db => db.ListLeftPush(key, ConvertJson(value)));
  586. }
  587. /// <summary>
  588. /// 出栈
  589. /// </summary>
  590. /// <typeparam name="T">数据类型</typeparam>
  591. /// <param name="key">键</param>
  592. /// <returns>对象实例</returns>
  593. public T ListLeftPop<T>(string key)
  594. {
  595. if (KeyExists(key))
  596. {
  597. key = AddSysCustomKey(key);
  598. return Do(db =>
  599. {
  600. var value = db.ListLeftPop(key);
  601. return ConvertObj<T>(value);
  602. });
  603. }
  604. return default(T);
  605. }
  606. /// <summary>
  607. /// 获取集合中的数量
  608. /// </summary>
  609. /// <param name="key">键</param>
  610. /// <returns>数量</returns>
  611. public long ListLength(string key)
  612. {
  613. key = AddSysCustomKey(key);
  614. return Do(redis => redis.ListLength(key));
  615. }
  616. #endregion 同步方法
  617. #region 异步方法
  618. /// <summary>
  619. /// 移除指定ListId的内部List的值
  620. /// </summary>
  621. /// <param name="key">键</param>
  622. /// <param name="value">值</param>
  623. public Task<long> RemoveListAsync<T>(string key, T value)
  624. {
  625. key = AddSysCustomKey(key);
  626. return Do(db => db.ListRemoveAsync(key, ConvertJson(value)));
  627. }
  628. /// <summary>
  629. /// 获取指定key的List
  630. /// </summary>
  631. /// <typeparam name="T">数据类型</typeparam>
  632. /// <param name="key">键</param>
  633. /// <returns>数据集合</returns>
  634. public async Task<List<T>> ListRangeAsync<T>(string key)
  635. {
  636. if (KeyExists(key))
  637. {
  638. key = AddSysCustomKey(key);
  639. var values = await Do(redis => redis.ListRangeAsync(key));
  640. return ConvetList<T>(values);
  641. }
  642. return new List<T>();
  643. }
  644. /// <summary>
  645. /// 入队
  646. /// </summary>
  647. /// <typeparam name="T">数据类型</typeparam>
  648. /// <param name="key">键</param>
  649. /// <param name="value">值</param>
  650. public async Task<long> ListRightPushAsync<T>(string key, T value)
  651. {
  652. key = AddSysCustomKey(key);
  653. return await Do(db => db.ListRightPushAsync(key, ConvertJson(value)));
  654. }
  655. /// <summary>
  656. /// 出队
  657. /// </summary>
  658. /// <typeparam name="T">数据类型</typeparam>
  659. /// <param name="key">键</param>
  660. /// <returns>对象实例</returns>
  661. public async Task<T> ListRightPopAsync<T>(string key)
  662. {
  663. if (KeyExists(key))
  664. {
  665. key = AddSysCustomKey(key);
  666. var value = await Do(db => db.ListRightPopAsync(key));
  667. return ConvertObj<T>(value);
  668. }
  669. return default(T);
  670. }
  671. /// <summary>
  672. /// 入栈
  673. /// </summary>
  674. /// <typeparam name="T">数据类型</typeparam>
  675. /// <param name="key">键</param>
  676. /// <param name="value">值</param>
  677. public async Task<long> ListLeftPushAsync<T>(string key, T value)
  678. {
  679. key = AddSysCustomKey(key);
  680. return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value)));
  681. }
  682. /// <summary>
  683. /// 出栈
  684. /// </summary>
  685. /// <typeparam name="T">数据类型</typeparam>
  686. /// <param name="key">键</param>
  687. /// <returns>实例对象</returns>
  688. public async Task<T> ListLeftPopAsync<T>(string key)
  689. {
  690. if (KeyExists(key))
  691. {
  692. key = AddSysCustomKey(key);
  693. var value = await Do(db => db.ListLeftPopAsync(key));
  694. return ConvertObj<T>(value);
  695. }
  696. return default(T);
  697. }
  698. /// <summary>
  699. /// 获取集合中的数量
  700. /// </summary>
  701. /// <param name="key">键</param>
  702. /// <returns>数量</returns>
  703. public async Task<long> ListLengthAsync(string key)
  704. {
  705. key = AddSysCustomKey(key);
  706. return await Do(redis => redis.ListLengthAsync(key));
  707. }
  708. #endregion 异步方法
  709. #endregion List
  710. #region SortedSet 有序集合
  711. #region 同步方法
  712. /// <summary>
  713. /// 添加
  714. /// </summary>
  715. /// <param name="key">键</param>
  716. /// <param name="value">值</param>
  717. /// <param name="score">排序号</param>
  718. public bool AddSortedSet<T>(string key, T value, double score)
  719. {
  720. key = AddSysCustomKey(key);
  721. return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score));
  722. }
  723. /// <summary>
  724. /// 删除
  725. /// </summary>
  726. /// <param name="key">键</param>
  727. /// <param name="value">值</param>
  728. public bool RemoveSortedSet<T>(string key, T value)
  729. {
  730. key = AddSysCustomKey(key);
  731. return Do(redis => redis.SortedSetRemove(key, ConvertJson(value)));
  732. }
  733. /// <summary>
  734. /// 获取全部
  735. /// </summary>
  736. /// <param name="key">键</param>
  737. /// <returns>数据集合</returns>
  738. public List<T> SetRangeSortedByRank<T>(string key)
  739. {
  740. if (KeyExists(key))
  741. {
  742. key = AddSysCustomKey(key);
  743. return Do(redis =>
  744. {
  745. var values = redis.SortedSetRangeByRank(key);
  746. return ConvetList<T>(values);
  747. });
  748. }
  749. return new List<T>();
  750. }
  751. /// <summary>
  752. /// 获取集合中的数量
  753. /// </summary>
  754. /// <param name="key">键</param>
  755. /// <returns>数量</returns>
  756. public long SetSortedLength(string key)
  757. {
  758. key = AddSysCustomKey(key);
  759. return Do(redis => redis.SortedSetLength(key));
  760. }
  761. #endregion 同步方法
  762. #region 异步方法
  763. /// <summary>
  764. /// 添加
  765. /// </summary>
  766. /// <param name="key">键</param>
  767. /// <param name="value">值</param>
  768. /// <param name="score">排序号</param>
  769. public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score)
  770. {
  771. key = AddSysCustomKey(key);
  772. return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score));
  773. }
  774. /// <summary>
  775. /// 删除
  776. /// </summary>
  777. /// <param name="key">键</param>
  778. /// <param name="value">值</param>
  779. public async Task<bool> SortedSetRemoveAsync<T>(string key, T value)
  780. {
  781. key = AddSysCustomKey(key);
  782. return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value)));
  783. }
  784. /// <summary>
  785. /// 获取全部
  786. /// </summary>
  787. /// <param name="key">键</param>
  788. /// <returns>数据集合</returns>
  789. public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key)
  790. {
  791. if (KeyExists(key))
  792. {
  793. key = AddSysCustomKey(key);
  794. var values = await Do(redis => redis.SortedSetRangeByRankAsync(key));
  795. return ConvetList<T>(values);
  796. }
  797. return new List<T>();
  798. }
  799. /// <summary>
  800. /// 获取集合中的数量
  801. /// </summary>
  802. /// <param name="key">键</param>
  803. /// <returns>数量</returns>
  804. public async Task<long> SortedSetLengthAsync(string key)
  805. {
  806. key = AddSysCustomKey(key);
  807. return await Do(redis => redis.SortedSetLengthAsync(key));
  808. }
  809. #endregion 异步方法
  810. #endregion SortedSet 有序集合
  811. #region key
  812. /// <summary>
  813. /// 删除单个key
  814. /// </summary>
  815. /// <param name="key">redis key</param>
  816. /// <returns>是否删除成功</returns>
  817. public bool DeleteKey(string key)
  818. {
  819. key = AddSysCustomKey(key);
  820. return Do(db => db.KeyDelete(key));
  821. }
  822. /// <summary>
  823. /// 删除多个key
  824. /// </summary>
  825. /// <param name="keys">rediskey</param>
  826. /// <returns>成功删除的个数</returns>
  827. public long DeleteKey(List<string> keys)
  828. {
  829. List<string> newKeys = keys.Select(AddSysCustomKey).ToList();
  830. return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys)));
  831. }
  832. /// <summary>
  833. /// 判断key是否存储
  834. /// </summary>
  835. /// <param name="key">键</param>
  836. /// <returns>是否存储成功</returns>
  837. public bool KeyExists(string key)
  838. {
  839. key = AddSysCustomKey(key);
  840. return Do(db => db.KeyExists(key));
  841. }
  842. /// <summary>
  843. /// 重新命名key
  844. /// </summary>
  845. /// <param name="key">旧的键</param>
  846. /// <param name="newKey">新的键</param>
  847. /// <returns>处理结果</returns>
  848. public bool RenameKey(string key, string newKey)
  849. {
  850. key = AddSysCustomKey(key);
  851. return Do(db => db.KeyRename(key, newKey));
  852. }
  853. /// <summary>
  854. /// 设置Key的过期时间
  855. /// </summary>
  856. /// <param name="key">键</param>
  857. /// <param name="expiry">过期时间</param>
  858. /// <returns>处理结果</returns>
  859. public bool Expire(string key, TimeSpan? expiry = default(TimeSpan?))
  860. {
  861. key = AddSysCustomKey(key);
  862. return Do(db => db.KeyExpire(key, expiry));
  863. }
  864. #endregion key
  865. #region 发布订阅
  866. /// <summary>
  867. /// Redis发布订阅 订阅
  868. /// </summary>
  869. /// <param name="subChannel">订阅频道</param>
  870. /// <param name="handler">处理过程</param>
  871. public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null)
  872. {
  873. ISubscriber sub = _conn.GetSubscriber();
  874. sub.Subscribe(subChannel, (channel, message) =>
  875. {
  876. if (handler == null)
  877. {
  878. Console.WriteLine(subChannel + " 订阅收到消息:" + message);
  879. }
  880. else
  881. {
  882. handler(channel, message);
  883. }
  884. });
  885. }
  886. /// <summary>
  887. /// Redis发布订阅 发布
  888. /// </summary>
  889. /// <typeparam name="T">消息对象</typeparam>
  890. /// <param name="channel">发布频道</param>
  891. /// <param name="msg">消息</param>
  892. /// <returns>消息的数量</returns>
  893. public long Publish<T>(string channel, T msg)
  894. {
  895. ISubscriber sub = _conn.GetSubscriber();
  896. return sub.Publish(channel, ConvertJson(msg));
  897. }
  898. /// <summary>
  899. /// Redis发布订阅 取消订阅
  900. /// </summary>
  901. /// <param name="channel">频道</param>
  902. public void Unsubscribe(string channel)
  903. {
  904. ISubscriber sub = _conn.GetSubscriber();
  905. sub.Unsubscribe(channel);
  906. }
  907. /// <summary>
  908. /// Redis发布订阅 取消全部订阅
  909. /// </summary>
  910. public void UnsubscribeAll()
  911. {
  912. ISubscriber sub = _conn.GetSubscriber();
  913. sub.UnsubscribeAll();
  914. }
  915. #endregion 发布订阅
  916. #region 其他
  917. /// <summary>
  918. /// 创建一个事务
  919. /// </summary>
  920. /// <returns>事务对象</returns>
  921. public ITransaction CreateTransaction()
  922. {
  923. return GetDatabase().CreateTransaction();
  924. }
  925. /// <summary>
  926. /// 获得一个数据库实例
  927. /// </summary>
  928. /// <returns>数据库实例</returns>
  929. public IDatabase GetDatabase()
  930. {
  931. return _conn.GetDatabase(DbNum);
  932. }
  933. /// <summary>
  934. /// 获得一个服务器实例
  935. /// </summary>
  936. /// <param name="hostAndPort">服务器地址</param>
  937. /// <returns>服务器实例</returns>
  938. public IServer GetServer(string hostAndPort)
  939. {
  940. return _conn.GetServer(hostAndPort);
  941. }
  942. /// <summary>
  943. /// 设置前缀
  944. /// </summary>
  945. /// <param name="customKey">前缀</param>
  946. public void SetSysCustomKey(string customKey)
  947. {
  948. CustomKey = customKey;
  949. }
  950. #endregion 其他
  951. #region 辅助方法
  952. private string AddSysCustomKey(string oldKey)
  953. {
  954. var prefixKey = CustomKey ?? String.Empty;
  955. return prefixKey + oldKey;
  956. }
  957. private T Do<T>(Func<IDatabase, T> func)
  958. {
  959. var database = _conn.GetDatabase(DbNum);
  960. return func(database);
  961. }
  962. private string ConvertJson<T>(T value)
  963. {
  964. return JsonConvert.SerializeObject(value);
  965. }
  966. private T ConvertObj<T>(RedisValue value)
  967. {
  968. return JsonConvert.DeserializeObject<T>(value);
  969. }
  970. private List<T> ConvetList<T>(RedisValue[] values)
  971. {
  972. List<T> result = new List<T>();
  973. foreach (var item in values)
  974. {
  975. var model = ConvertObj<T>(item);
  976. result.Add(model);
  977. }
  978. return result;
  979. }
  980. private RedisKey[] ConvertRedisKeys(List<string> redisKeys)
  981. {
  982. return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray();
  983. }
  984. #endregion 辅助方法
  985. }
  986. }