|
1 #region
2
3 using System;
4 using System.Collections.Generic;
5 using System.Configuration;
6 using System.IO;
7 using System.Linq;
8 using System.Runtime.Serialization.Formatters.Binary;
9 using System.Threading.Tasks;
10 using StackExchange.Redis;
11
12 #endregion
13
14 namespace Wen.Helpers.Common.Redis
15 {
16 /// <summary>
17 /// Redis 助手
18 /// </summary>
19 public>
20 {
21 /// <summary>
22 /// 获取 Redis 连接对象
23 /// </summary>
24 /// <returns></returns>
25 public IConnectionMultiplexer GetConnectionRedisMultiplexer()
26 {
27 if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
28 lock (Locker)
29 {
30 if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
31 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
32 }
33
34 return _connMultiplexer;
35 }
36
37 #region 其它
38
39 public ITransaction GetTransaction()
40 {
41 return _db.CreateTransaction();
42 }
43
44 #endregion 其它
45
46 #region private field
47
48 /// <summary>
49 /// 连接字符串
50 /// </summary>
51 private static readonly string ConnectionString;
52
53 /// <summary>
54 /// redis 连接对象
55 /// </summary>
56 private static IConnectionMultiplexer _connMultiplexer;
57
58 /// <summary>
59 /// 默认的 Key 值(用来当作 RedisKey 的前缀)
60 /// </summary>
61 private static readonly string DefaultKey;
62
63 /// <summary>
64 /// 锁
65 /// </summary>
66 private static readonly object Locker = new object();
67
68 /// <summary>
69 /// 数据库
70 /// </summary>
71 private readonly>
72
73 #endregion private field
74
75 #region 构造函数
76
77 static RedisHelper()
78 {
79 ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
80 _connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
81 DefaultKey = ConfigurationManager.AppSettings["Redis.DefaultKey"];
82 AddRegisterEvent();
83 }
84
85 public RedisHelper(int db = 0)
86 {
87 _db = _connMultiplexer.GetDatabase(db);
88 }
89
90 #endregion 构造函数
91
92 #region String 操作
93
94 /// <summary>
95 /// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
96 /// </summary>
97 /// <param name="key"></param>
98 /// <param name="value"></param>
99 /// <param name="expiry"></param>
100 /// <returns></returns>
101 public bool StringSet(string key, string value, TimeSpan? expiry = null)
102 {
103 key = AddKeyPrefix(key);
104 return _db.StringSet(key, value, expiry);
105 }
106
107 /// <summary>
108 /// 保存多个 Key-value
109 /// </summary>
110 /// <param name="keyValuePairs"></param>
111 /// <returns></returns>
112 public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
113 {
114 var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
115 return _db.StringSet(pairs.ToArray());
116 }
117
118 /// <summary>
119 /// 获取字符串
120 /// </summary>
121 /// <param name="redisKey"></param>
122 /// <param name="expiry"></param>
123 /// <returns></returns>
124 public string StringGet(string redisKey)
125 {
126 redisKey = AddKeyPrefix(redisKey);
127 return _db.StringGet(redisKey);
128 }
129
130 /// <summary>
131 /// 存储一个对象(该对象会被序列化保存)
132 /// </summary>
133 /// <param name="key"></param>
134 /// <param name="value"></param>
135 /// <param name="expiry"></param>
136 /// <returns></returns>
137 public bool StringSet<T>(string key, T value, TimeSpan? expiry = null)
138 {
139 key = AddKeyPrefix(key);
140 var json = Serialize(value);
141
142 return _db.StringSet(key, json, expiry);
143 }
144
145 /// <summary>
146 /// 获取一个对象(会进行反序列化)
147 /// </summary>
148 /// <param name="key"></param>
149 /// <param name="expiry"></param>
150 /// <returns></returns>
151 public T StringGet<T>(string key, TimeSpan? expiry = null)
152 {
153 key = AddKeyPrefix(key);
154 return Deserialize<T>(_db.StringGet(key));
155 }
156
157 /// <summary>
158 /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
159 /// </summary>
160 /// <param name="key"></param>
161 /// <param name="value"></param>
162 /// <returns></returns>
163 public double StringIncrement(string key, double value = 1)
164 {
165 key = AddKeyPrefix(key);
166 return _db.StringIncrement(key, value);
167 }
168
169 /// <summary>
170 /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
171 /// </summary>
172 /// <param name="key"></param>
173 /// <param name="value"></param>
174 /// <returns></returns>
175 public double StringDecrement(string key, double value = 1)
176 {
177 key = AddKeyPrefix(key);
178 return _db.StringDecrement(key, value);
179 }
180
181 #region async
182
183 /// <summary>
184 /// 保存一个字符串值
185 /// </summary>
186 /// <param name="key"></param>
187 /// <param name="value"></param>
188 /// <param name="expiry"></param>
189 /// <returns></returns>
190 public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null)
191 {
192 key = AddKeyPrefix(key);
193 return await _db.StringSetAsync(key, value, expiry);
194 }
195
196 /// <summary>
197 /// 保存一组字符串值
198 /// </summary>
199 /// <param name="keyValuePairs"></param>
200 /// <returns></returns>
201 public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
202 {
203 var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
204 return await _db.StringSetAsync(pairs.ToArray());
205 }
206
207 /// <summary>
208 /// 获取单个值
209 /// </summary>
210 /// <param name="key"></param>
211 /// <param name="value"></param>
212 /// <param name="expiry"></param>
213 /// <returns></returns>
214 public async Task<string> StringGetAsync(string key, string value, TimeSpan? expiry = null)
215 {
216 key = AddKeyPrefix(key);
217 return await _db.StringGetAsync(key);
218 }
219
220 /// <summary>
221 /// 存储一个对象(该对象会被序列化保存)
222 /// </summary>
223 /// <param name="key"></param>
224 /// <param name="value"></param>
225 /// <param name="expiry"></param>
226 /// <returns></returns>
227 public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
228 {
229 key = AddKeyPrefix(key);
230 var json = Serialize(value);
231 return await _db.StringSetAsync(key, json, expiry);
232 }
233
234 /// <summary>
235 /// 获取一个对象(会进行反序列化)
236 /// </summary>
237 /// <param name="key"></param>
238 /// <param name="expiry"></param>
239 /// <returns></returns>
240 public async Task<T> StringGetAsync<T>(string key, TimeSpan? expiry = null)
241 {
242 key = AddKeyPrefix(key);
243 return Deserialize<T>(await _db.StringGetAsync(key));
244 }
245
246 /// <summary>
247 /// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
248 /// </summary>
249 /// <param name="key"></param>
250 /// <param name="value"></param>
251 /// <returns></returns>
252 public async Task<double> StringIncrementAsync(string key, double value = 1)
253 {
254 key = AddKeyPrefix(key);
255 return await _db.StringIncrementAsync(key, value);
256 }
257
258 /// <summary>
259 /// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
260 /// </summary>
261 /// <param name="key"></param>
262 /// <param name="value"></param>
263 /// <returns></returns>
264 public async Task<double> StringDecrementAsync(string key, double value = 1)
265 {
266 key = AddKeyPrefix(key);
267 return await _db.StringDecrementAsync(key, value);
268 }
269
270 #endregion async
271
272 #endregion String 操作
273
274 #region Hash 操作
275
276 /// <summary>
277 /// 判断该字段是否存在 hash 中
278 /// </summary>
279 /// <param name="key"></param>
280 /// <param name="hashField"></param>
281 /// <returns></returns>
282 public bool HashExists(string key, string hashField)
283 {
284 key = AddKeyPrefix(key);
285 return _db.HashExists(key, hashField);
286 }
287
288 /// <summary>
289 /// 从 hash 中移除指定字段
290 /// </summary>
291 /// <param name="key"></param>
292 /// <param name="hashField"></param>
293 /// <returns></returns>
294 public bool HashDelete(string key, string hashField)
295 {
296 key = AddKeyPrefix(key);
297 return _db.HashDelete(key, hashField);
298 }
299
300 /// <summary>
301 /// 从 hash 中移除指定字段
302 /// </summary>
303 /// <param name="key"></param>
304 /// <param name="hashFields"></param>
305 /// <returns></returns>
306 public long HashDelete(string key, IEnumerable<string> hashFields)
307 {
308 key = AddKeyPrefix(key);
309 var fields = hashFields.Select(x => (RedisValue) x);
310
311 return _db.HashDelete(key, fields.ToArray());
312 }
313
314 /// <summary>
315 /// 在 hash 设定值
316 /// </summary>
317 /// <param name="key"></param>
318 /// <param name="hashField"></param>
319 /// <param name="value"></param>
320 /// <returns></returns>
321 public bool HashSet(string key, string hashField, string value)
322 {
323 key = AddKeyPrefix(key);
324 return _db.HashSet(key, hashField, value);
325 }
326
327 /// <summary>
328 /// 在 hash 中设定值
329 /// </summary>
330 /// <param name="key"></param>
331 /// <param name="hashFields"></param>
332 public void HashSet(string key, IEnumerable<KeyValuePair<string, string>> hashFields)
333 {
334 key = AddKeyPrefix(key);
335 var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value));
336
337 _db.HashSet(key, entries.ToArray());
338 }
339
340 /// <summary>
341 /// 在 hash 中获取值
342 /// </summary>
343 /// <param name="key"></param>
344 /// <param name="hashField"></param>
345 /// <returns></returns>
346 public string HashGet(string key, string hashField)
347 {
348 key = AddKeyPrefix(key);
349 return _db.HashGet(key, hashField);
350 }
351
352 /// <summary>
353 /// 在 hash 中获取值
354 /// </summary>
355 /// <param name="key"></param>
356 /// <param name="hashFields"></param>
357 /// <returns></returns>
358 public IEnumerable<string> HashGet(string key, IEnumerable<string> hashFields)
359 {
360 key = AddKeyPrefix(key);
361 var fields = hashFields.Select(x => (RedisValue) x);
362
363 return ConvertStrings(_db.HashGet(key, fields.ToArray()));
364 }
365
366 /// <summary>
367 /// 从 hash 返回所有的字段值
368 /// </summary>
369 /// <param name="key"></param>
370 /// <returns></returns>
371 public IEnumerable<string> HashKeys(string key)
372 {
373 key = AddKeyPrefix(key);
374 return ConvertStrings(_db.HashKeys(key));
375 }
376
377 /// <summary>
378 /// 返回 hash 中的所有值
379 /// </summary>
380 /// <param name="key"></param>
381 /// <returns></returns>
382 public IEnumerable<string> HashValues(string key)
383 {
384 key = AddKeyPrefix(key);
385 return ConvertStrings(_db.HashValues(key));
386 }
387
388 /// <summary>
389 /// 在 hash 设定值(序列化)
390 /// </summary>
391 /// <param name="key"></param>
392 /// <param name="hashField"></param>
393 /// <param name="redisValue"></param>
394 /// <returns></returns>
395 public bool HashSet<T>(string key, string hashField, T redisValue)
396 {
397 key = AddKeyPrefix(key);
398 var json = Serialize(redisValue);
399
400 return _db.HashSet(key, hashField, json);
401 }
402
403 /// <summary>
404 /// 在 hash 中获取值(反序列化)
405 /// </summary>
406 /// <param name="key"></param>
407 /// <param name="hashField"></param>
408 /// <returns></returns>
409 public T HashGet<T>(string key, string hashField)
410 {
411 key = AddKeyPrefix(key);
412 return Deserialize<T>(_db.HashGet(key, hashField));
413 }
414
415 /// <summary>
416 /// 指定键递增
417 /// </summary>
418 /// <param name="key"></param>
419 /// <param name="hashField"></param>
420 /// <param name="value"></param>
421 /// <returns></returns>
422 public double HashIncrement(string key, string hashField, double value = 1)
423 {
424 key = AddKeyPrefix(key);
425 return _db.HashIncrement(key, hashField, value);
426 }
427
428 /// <summary>
429 /// 指定键递减
430 /// </summary>
431 /// <param name="key"></param>
432 /// <param name="hashField"></param>
433 /// <param name="value"></param>
434 /// <returns></returns>
435 public double HashDecrement(string key, string hashField, double value = 1)
436 {
437 key = AddKeyPrefix(key);
438 return _db.HashDecrement(key, hashField, value);
439 }
440
441 #region async
442
443 /// <summary>
444 /// 判断该字段是否存在 hash 中
445 /// </summary>
446 /// <param name="redisKey"></param>
447 /// <param name="hashField"></param>
448 /// <returns></returns>
449 public async Task<bool> HashExistsAsync(string redisKey, string hashField)
450 {
451 redisKey = AddKeyPrefix(redisKey);
452 return await _db.HashExistsAsync(redisKey, hashField);
453 }
454
455 /// <summary>
456 /// 从 hash 中移除指定字段
457 /// </summary>
458 /// <param name="redisKey"></param>
459 /// <param name="hashField"></param>
460 /// <returns></returns>
461 public async Task<bool> HashDeleteAsync(string redisKey, string hashField)
462 {
463 redisKey = AddKeyPrefix(redisKey);
464 return await _db.HashDeleteAsync(redisKey, hashField);
465 }
466
467 /// <summary>
468 /// 从 hash 中移除指定字段
469 /// </summary>
470 /// <param name="redisKey"></param>
471 /// <param name="hashFields"></param>
472 /// <returns></returns>
473 public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields)
474 {
475 redisKey = AddKeyPrefix(redisKey);
476 var fields = hashFields.Select(x => (RedisValue) x);
477
478 return await _db.HashDeleteAsync(redisKey, fields.ToArray());
479 }
480
481 /// <summary>
482 /// 在 hash 设定值
483 /// </summary>
484 /// <param name="redisKey"></param>
485 /// <param name="hashField"></param>
486 /// <param name="value"></param>
487 /// <returns></returns>
488 public async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
489 {
490 redisKey = AddKeyPrefix(redisKey);
491 return await _db.HashSetAsync(redisKey, hashField, value);
492 }
493
494 /// <summary>
495 /// 在 hash 中设定值
496 /// </summary>
497 /// <param name="redisKey"></param>
498 /// <param name="hashFields"></param>
499 public async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
500 {
501 redisKey = AddKeyPrefix(redisKey);
502 var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value));
503 await _db.HashSetAsync(redisKey, entries.ToArray());
504 }
505
506 /// <summary>
507 /// 在 hash 中获取值
508 /// </summary>
509 /// <param name="redisKey"></param>
510 /// <param name="hashField"></param>
511 /// <returns></returns>
512 public async Task<string> HashGetAsync(string redisKey, string hashField)
513 {
514 redisKey = AddKeyPrefix(redisKey);
515 return await _db.HashGetAsync(redisKey, hashField);
516 }
517
518 /// <summary>
519 /// 在 hash 中获取值
520 /// </summary>
521 /// <param name="redisKey"></param>
522 /// <param name="hashFields"></param>
523 /// <param name="value"></param>
524 /// <returns></returns>
525 public async Task<IEnumerable<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields,
526 string value)
527 {
528 redisKey = AddKeyPrefix(redisKey);
529 var fields = hashFields.Select(x => (RedisValue) x);
530
531 return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray()));
532 }
533
534 /// <summary>
535 /// 从 hash 返回所有的字段值
536 /// </summary>
537 /// <param name="redisKey"></param>
538 /// <returns></returns>
539 public async Task<IEnumerable<string>> HashKeysAsync(string redisKey)
540 {
541 redisKey = AddKeyPrefix(redisKey);
542 return ConvertStrings(await _db.HashKeysAsync(redisKey));
543 }
544
545 /// <summary>
546 /// 返回 hash 中的所有值
547 /// </summary>
548 /// <param name="redisKey"></param>
549 /// <returns></returns>
550 public async Task<IEnumerable<string>> HashValuesAsync(string redisKey)
551 {
552 redisKey = AddKeyPrefix(redisKey);
553 return ConvertStrings(await _db.HashValuesAsync(redisKey));
554 }
555
556 /// <summary>
557 /// 在 hash 设定值(序列化)
558 /// </summary>
559 /// <param name="redisKey"></param>
560 /// <param name="hashField"></param>
561 /// <param name="value"></param>
562 /// <returns></returns>
563 public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
564 {
565 redisKey = AddKeyPrefix(redisKey);
566 var json = Serialize(value);
567 return await _db.HashSetAsync(redisKey, hashField, json);
568 }
569
570 /// <summary>
571 /// 在 hash 中获取值(反序列化)
572 /// </summary>
573 /// <param name="redisKey"></param>
574 /// <param name="hashField"></param>
575 /// <returns></returns>
576 public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
577 {
578 redisKey = AddKeyPrefix(redisKey);
579 return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));
580 }
581
582 /// <summary>
583 /// 指定键递增
584 /// </summary>
585 /// <param name="key"></param>
586 /// <param name="hashField"></param>
587 /// <param name="value"></param>
588 /// <returns></returns>
589 public async Task<double> HashIncrementAsync(string key, string hashField, double value = 1)
590 {
591 key = AddKeyPrefix(key);
592 return await _db.HashIncrementAsync(key, hashField, value);
593 }
594
595 /// <summary>
596 /// 指定键递减
597 /// </summary>
598 /// <param name="key"></param>
599 /// <param name="hashField"></param>
600 /// <param name="value"></param>
601 /// <returns></returns>
602 public async Task<double> HashDecrementAsync(string key, string hashField, double value = 1)
603 {
604 key = AddKeyPrefix(key);
605 return await _db.HashDecrementAsync(key, hashField, value);
606 }
607
608 #endregion async
609
610 #endregion Hash 操作
611
612 #region List 操作
613
614 /// <summary>
615 /// 移除并返回存储在该键列表的第一个元素
616 /// </summary>
617 /// <param name="key"></param>
618 /// <returns></returns>
619 public string ListLeftPop(string key)
620 {
621 key = AddKeyPrefix(key);
622 return _db.ListLeftPop(key);
623 }
624
625 /// <summary>
626 /// 出列,移除并返回存储在该键列表的最后一个元素
627 /// </summary>
628 /// <param name="key"></param>
629 /// <returns></returns>
630 public string ListRightPop(string key)
631 {
632 key = AddKeyPrefix(key);
633 return _db.ListRightPop(key);
634 }
635
636 /// <summary>
637 /// 移除列表指定键上与该值相同的元素
638 /// </summary>
639 /// <param name="key"></param>
640 /// <param name="value"></param>
641 /// <returns></returns>
642 public long ListRemove(string key, string value)
643 {
644 key = AddKeyPrefix(key);
645 return _db.ListRemove(key, value);
646 }
647
648 /// <summary>
649 /// 入列,在列表尾部插入值。如果键不存在,先创建再插入值
650 /// </summary>
651 /// <param name="key"></param>
652 /// <param name="value"></param>
653 /// <returns></returns>
654 public long ListRightPush(string key, string value)
655 {
656 key = AddKeyPrefix(key);
657 return _db.ListRightPush(key, value);
658 }
659
660 /// <summary>
661 /// 在列表头部插入值。如果键不存在,先创建再插入值
662 /// </summary>
663 /// <param name="key"></param>
664 /// <param name="value"></param>
665 /// <returns></returns>
666 public long ListLeftPush(string key, string value)
667 {
668 key = AddKeyPrefix(key);
669 return _db.ListLeftPush(key, value);
670 }
671
672 /// <summary>
673 /// 返回列表上该键的长度,如果不存在,返回 0
674 /// </summary>
675 /// <param name="key"></param>
676 /// <returns></returns>
677 public long ListLength(string key)
678 {
679 key = AddKeyPrefix(key);
680 return _db.ListLength(key);
681 }
682
683 /// <summary>
684 /// 返回在该列表上键所对应的元素
685 /// </summary>
686 /// <param name="key"></param>
687 /// <param name="start"></param>
688 /// <param name="stop"></param>
689 /// <returns></returns>
690 public IEnumerable<string> ListRange(string key, long start = 0L, long stop = -1L)
691 {
692 key = AddKeyPrefix(key);
693 return ConvertStrings(_db.ListRange(key, start, stop));
694 }
695
696 /// <summary>
697 /// 移除并返回存储在该键列表的第一个元素
698 /// </summary>
699 /// <param name="key"></param>
700 /// <returns></returns>
701 public T ListLeftPop<T>(string key)
702 {
703 key = AddKeyPrefix(key);
704 return Deserialize<T>(_db.ListLeftPop(key));
705 }
706
707 /// <summary>
708 /// 出队,移除并返回存储在该键列表的最后一个元素
709 /// </summary>
710 /// <param name="key"></param>
711 /// <returns></returns>
712 public T ListRightPop<T>(string key)
713 {
714 key = AddKeyPrefix(key);
715 return Deserialize<T>(_db.ListRightPop(key));
716 }
717
718 /// <summary>
719 /// 入队,在列表尾部插入值。如果键不存在,先创建再插入值
720 /// </summary>
721 /// <param name="key"></param>
722 /// <param name="value"></param>
723 /// <returns></returns>
724 public long ListRightPush<T>(string key, T value)
725 {
726 key = AddKeyPrefix(key);
727 return _db.ListRightPush(key, Serialize(value));
728 }
729
730 /// <summary>
731 /// 在列表头部插入值。如果键不存在,先创建再插入值
732 /// </summary>
733 /// <param name="key"></param>
734 /// <param name="value"></param>
735 /// <returns></returns>
736 public long ListLeftPush<T>(string key, T value)
737 {
738 key = AddKeyPrefix(key);
739 return _db.ListLeftPush(key, Serialize(value));
740 }
741
742 #region List-async
743
744 /// <summary>
745 /// 移除并返回存储在该键列表的第一个元素
746 /// </summary>
747 /// <param name="key"></param>
748 /// <returns></returns>
749 public async Task<string> ListLeftPopAsync(string key)
750 {
751 key = AddKeyPrefix(key);
752 return await _db.ListLeftPopAsync(key);
753 }
754
755 /// <summary>
756 /// 移除并返回存储在该键列表的最后一个元素
757 /// </summary>
758 /// <param name="key"></param>
759 /// <returns></returns>
760 public async Task<string> ListRightPopAsync(string key)
761 {
762 key = AddKeyPrefix(key);
763 return await _db.ListRightPopAsync(key);
764 }
765
766 /// <summary>
767 /// 移除列表指定键上与该值相同的元素
768 /// </summary>
769 /// <param name="key"></param>
770 /// <param name="value"></param>
771 /// <returns></returns>
772 public async Task<long> ListRemoveAsync(string key, string value)
773 {
774 key = AddKeyPrefix(key);
775 return await _db.ListRemoveAsync(key, value);
776 }
777
778 /// <summary>
779 /// 在列表尾部插入值。如果键不存在,先创建再插入值
780 /// </summary>
781 /// <param name="key"></param>
782 /// <param name="value"></param>
783 /// <returns></returns>
784 public async Task<long> ListRightPushAsync(string key, string value)
785 {
786 key = AddKeyPrefix(key);
787 return await _db.ListRightPushAsync(key, value);
788 }
789
790 /// <summary>
791 /// 在列表头部插入值。如果键不存在,先创建再插入值
792 /// </summary>
793 /// <param name="key"></param>
794 /// <param name="value"></param>
795 /// <returns></returns>
796 public async Task<long> ListLeftPushAsync(string key, string value)
797 {
798 key = AddKeyPrefix(key);
799 return await _db.ListLeftPushAsync(key, value);
800 }
801
802 /// <summary>
803 /// 返回列表上该键的长度,如果不存在,返回 0
804 /// </summary>
805 /// <param name="key"></param>
806 /// <returns></returns>
807 public async Task<long> ListLengthAsync(string key)
808 {
809 key = AddKeyPrefix(key);
810 return await _db.ListLengthAsync(key);
811 }
812
813 /// <summary>
814 /// 返回在该列表上键所对应的元素
815 /// </summary>
816 /// <param name="key"></param>
817 /// <param name="start"></param>
818 /// <param name="stop"></param>
819 /// <returns></returns>
820 public async Task<IEnumerable<string>> ListRangeAsync(string key, long start = 0L, long stop = -1L)
821 {
822 key = AddKeyPrefix(key);
823 var query = await _db.ListRangeAsync(key, start, stop);
824 return query.Select(x => x.ToString());
825 }
826
827 /// <summary>
828 /// 移除并返回存储在该键列表的第一个元素
829 /// </summary>
830 /// <param name="key"></param>
831 /// <returns></returns>
832 public async Task<T> ListLeftPopAsync<T>(string key)
833 {
834 key = AddKeyPrefix(key);
835 return Deserialize<T>(await _db.ListLeftPopAsync(key));
836 }
837
838 /// <summary>
839 /// 移除并返回存储在该键列表的最后一个元素
840 /// </summary>
841 /// <param name="key"></param>
842 /// <returns></returns>
843 public async Task<T> ListRightPopAsync<T>(string key)
844 {
845 key = AddKeyPrefix(key);
846 return Deserialize<T>(await _db.ListRightPopAsync(key));
847 }
848
849 /// <summary>
850 /// 在列表尾部插入值。如果键不存在,先创建再插入值
851 /// </summary>
852 /// <param name="key"></param>
853 /// <param name="value"></param>
854 /// <returns></returns>
855 public async Task<long> ListRightPushAsync<T>(string key, T value)
856 {
857 key = AddKeyPrefix(key);
858 return await _db.ListRightPushAsync(key, Serialize(value));
859 }
860
861 /// <summary>
862 /// 在列表头部插入值。如果键不存在,先创建再插入值
863 /// </summary>
864 /// <param name="key"></param>
865 /// <param name="value"></param>
866 /// <returns></returns>
867 public async Task<long> ListLeftPushAsync<T>(string key, T value)
868 {
869 key = AddKeyPrefix(key);
870 return await _db.ListLeftPushAsync(key, Serialize(value));
871 }
872
873 #endregion List-async
874
875 #endregion List 操作
876
877 #region SortedSet 操作
878
879 /// <summary>
880 /// SortedSet 新增
881 /// </summary>
882 /// <param name="key"></param>
883 /// <param name="member"></param>
884 /// <param name="score"></param>
885 /// <returns></returns>
886 public bool SortedSetAdd(string key, string member, double score)
887 {
888 key = AddKeyPrefix(key);
889 return _db.SortedSetAdd(key, member, score);
890 }
891
892 /// <summary>
893 /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
894 /// </summary>
895 /// <param name="key"></param>
896 /// <param name="start"></param>
897 /// <param name="stop"></param>
898 /// <param name="order"></param>
899 /// <returns></returns>
900 public IEnumerable<string> SortedSetRangeByRank(string key, long start = 0L, long stop = -1L,
901 OrderType order = OrderType.Ascending)
902 {
903 key = AddKeyPrefix(key);
904 return _db.SortedSetRangeByRank(key, start, stop, (Order) order).Select(x => x.ToString());
905 }
906
907 /// <summary>
908 /// 返回有序集合的元素个数
909 /// </summary>
910 /// <param name="key"></param>
911 /// <returns></returns>
912 public long SortedSetLength(string key)
913 {
914 key = AddKeyPrefix(key);
915 return _db.SortedSetLength(key);
916 }
917
918 /// <summary>
919 /// 返回有序集合的元素个数
920 /// </summary>
921 /// <param name="key"></param>
922 /// <param name="memebr"></param>
923 /// <returns></returns>
924 public bool SortedSetRemove(string key, string memebr)
925 {
926 key = AddKeyPrefix(key);
927 return _db.SortedSetRemove(key, memebr);
928 }
929
930 /// <summary>
931 /// SortedSet 新增
932 /// </summary>
933 /// <param name="key"></param>
934 /// <param name="member"></param>
935 /// <param name="score"></param>
936 /// <returns></returns>
937 public bool SortedSetAdd<T>(string key, T member, double score)
938 {
939 key = AddKeyPrefix(key);
940 var json = Serialize(member);
941
942 return _db.SortedSetAdd(key, json, score);
943 }
944
945 /// <summary>
946 /// 增量的得分排序的集合中的成员存储键值键按增量
947 /// </summary>
948 /// <param name="key"></param>
949 /// <param name="member"></param>
950 /// <param name="value"></param>
951 /// <returns></returns>
952 public double SortedSetIncrement(string key, string member, double value = 1)
953 {
954 key = AddKeyPrefix(key);
955 return _db.SortedSetIncrement(key, member, value);
956 }
957
958 #region SortedSet-Async
959
960 /// <summary>
961 /// SortedSet 新增
962 /// </summary>
963 /// <param name="key"></param>
964 /// <param name="member"></param>
965 /// <param name="score"></param>
966 /// <returns></returns>
967 public async Task<bool> SortedSetAddAsync(string key, string member, double score)
968 {
969 key = AddKeyPrefix(key);
970 return await _db.SortedSetAddAsync(key, member, score);
971 }
972
973 /// <summary>
974 /// 在有序集合中返回指定范围的元素,默认情况下从低到高。
975 /// </summary>
976 /// <param name="key"></param>
977 /// <returns></returns>
978 public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string key)
979 {
980 key = AddKeyPrefix(key);
981 return ConvertStrings(await _db.SortedSetRangeByRankAsync(key));
982 }
983
984 /// <summary>
985 /// 返回有序集合的元素个数
986 /// </summary>
987 /// <param name="key"></param>
988 /// <returns></returns>
989 public async Task<long> SortedSetLengthAsync(string key)
990 {
991 key = AddKeyPrefix(key);
992 return await _db.SortedSetLengthAsync(key);
993 }
994
995 /// <summary>
996 /// 返回有序集合的元素个数
997 /// </summary>
998 /// <param name="key"></param>
999 /// <param name="memebr"></param>
1000 /// <returns></returns>
1001 public async Task<bool> SortedSetRemoveAsync(string key, string memebr)
1002 {
1003 key = AddKeyPrefix(key);
1004 return await _db.SortedSetRemoveAsync(key, memebr);
1005 }
1006
1007 /// <summary>
1008 /// SortedSet 新增
1009 /// </summary>
1010 /// <param name="key"></param>
1011 /// <param name="member"></param>
1012 /// <param name="score"></param>
1013 /// <returns></returns>
1014 public async Task<bool> SortedSetAddAsync<T>(string key, T member, double score)
1015 {
1016 key = AddKeyPrefix(key);
1017 var json = Serialize(member);
1018
1019 return await _db.SortedSetAddAsync(key, json, score);
1020 }
1021
1022 /// <summary>
1023 /// 增量的得分排序的集合中的成员存储键值键按增量
1024 /// </summary>
1025 /// <param name="key"></param>
1026 /// <param name="member"></param>
1027 /// <param name="value"></param>
1028 /// <returns></returns>
1029 public Task<double> SortedSetIncrementAsync(string key, string member, double value = 1)
1030 {
1031 key = AddKeyPrefix(key);
1032 return _db.SortedSetIncrementAsync(key, member, value);
1033 }
1034
1035 #endregion SortedSet-Async
1036
1037 #endregion SortedSet 操作
1038
1039 #region key 操作
1040
1041 /// <summary>
1042 /// 移除指定 Key
1043 /// </summary>
1044 /// <param name="key"></param>
1045 /// <returns></returns>
1046 public bool KeyDelete(string key)
1047 {
1048 key = AddKeyPrefix(key);
1049 return _db.KeyDelete(key);
1050 }
1051
1052 /// <summary>
1053 /// 移除指定 Key
1054 /// </summary>
1055 /// <param name="keys"></param>
1056 /// <returns></returns>
1057 public long KeyDelete(IEnumerable<string> keys)
1058 {
1059 var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
1060 return _db.KeyDelete(redisKeys.ToArray());
1061 }
1062
1063 /// <summary>
1064 /// 校验 Key 是否存在
1065 /// </summary>
1066 /// <param name="key"></param>
1067 /// <returns></returns>
1068 public bool KeyExists(string key)
1069 {
1070 key = AddKeyPrefix(key);
1071 return _db.KeyExists(key);
1072 }
1073
1074 /// <summary>
1075 /// 重命名 Key
1076 /// </summary>
1077 /// <param name="key"></param>
1078 /// <param name="newKey"></param>
1079 /// <returns></returns>
1080 public bool KeyRename(string key, string newKey)
1081 {
1082 key = AddKeyPrefix(key);
1083 return _db.KeyRename(key, newKey);
1084 }
1085
1086 /// <summary>
1087 /// 设置 Key 的时间
1088 /// </summary>
1089 /// <param name="key"></param>
1090 /// <param name="expiry"></param>
1091 /// <returns></returns>
1092 public bool KeyExpire(string key, TimeSpan? expiry)
1093 {
1094 key = AddKeyPrefix(key);
1095 return _db.KeyExpire(key, expiry);
1096 }
1097
1098 #region key-async
1099
1100 /// <summary>
1101 /// 移除指定 Key
1102 /// </summary>
1103 /// <param name="key"></param>
1104 /// <returns></returns>
1105 public async Task<bool> KeyDeleteAsync(string key)
1106 {
1107 key = AddKeyPrefix(key);
1108 return await _db.KeyDeleteAsync(key);
1109 }
1110
1111 /// <summary>
1112 /// 移除指定 Key
1113 /// </summary>
1114 /// <param name="keys"></param>
1115 /// <returns></returns>
1116 public async Task<long> KeyDeleteAsync(IEnumerable<string> keys)
1117 {
1118 var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
1119 return await _db.KeyDeleteAsync(redisKeys.ToArray());
1120 }
1121
1122 /// <summary>
1123 /// 校验 Key 是否存在
1124 /// </summary>
1125 /// <param name="key"></param>
1126 /// <returns></returns>
1127 public async Task<bool> KeyExistsAsync(string key)
1128 {
1129 key = AddKeyPrefix(key);
1130 return await _db.KeyExistsAsync(key);
1131 }
1132
1133 /// <summary>
1134 /// 重命名 Key
1135 /// </summary>
1136 /// <param name="key"></param>
1137 /// <param name="newKey"></param>
1138 /// <returns></returns>
1139 public async Task<bool> KeyRenameAsync(string key, string newKey)
1140 {
1141 key = AddKeyPrefix(key);
1142 return await _db.KeyRenameAsync(key, newKey);
1143 }
1144
1145 /// <summary>
1146 /// 设置 Key 的时间
1147 /// </summary>
1148 /// <param name="key"></param>
1149 /// <param name="expiry"></param>
1150 /// <returns></returns>
1151 public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
1152 {
1153 key = AddKeyPrefix(key);
1154 return await _db.KeyExpireAsync(key, expiry);
1155 }
1156
1157 #endregion key-async
1158
1159 #endregion key 操作
1160
1161 #region 发布订阅
1162
1163 /// <summary>
1164 /// 订阅
1165 /// </summary>
1166 /// <param name="channel"></param>
1167 /// <param name="handle"></param>
1168 public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1169 {
1170 var sub = _connMultiplexer.GetSubscriber();
1171 sub.Subscribe(channel, handle);
1172 }
1173
1174 /// <summary>
1175 /// 发布
1176 /// </summary>
1177 /// <param name="channel"></param>
1178 /// <param name="message"></param>
1179 /// <returns></returns>
1180 public long Publish(RedisChannel channel, RedisValue message)
1181 {
1182 var sub = _connMultiplexer.GetSubscriber();
1183 return sub.Publish(channel, message);
1184 }
1185
1186 /// <summary>
1187 /// 发布(使用序列化)
1188 /// </summary>
1189 /// <typeparam name="T"></typeparam>
1190 /// <param name="channel"></param>
1191 /// <param name="message"></param>
1192 /// <returns></returns>
1193 public long Publish<T>(RedisChannel channel, T message)
1194 {
1195 var sub = _connMultiplexer.GetSubscriber();
1196 return sub.Publish(channel, Serialize(message));
1197 }
1198
1199 #region 发布订阅-async
1200
1201 /// <summary>
1202 /// 订阅
1203 /// </summary>
1204 /// <param name="channel"></param>
1205 /// <param name="handle"></param>
1206 public async Task SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
1207 {
1208 var sub = _connMultiplexer.GetSubscriber();
1209 await sub.SubscribeAsync(channel, handle);
1210 }
1211
1212 /// <summary>
1213 /// 发布
1214 /// </summary>
1215 /// <param name="channel"></param>
1216 /// <param name="message"></param>
1217 /// <returns></returns>
1218 public async Task<long> PublishAsync(RedisChannel channel, RedisValue message)
1219 {
1220 var sub = _connMultiplexer.GetSubscriber();
1221 return await sub.PublishAsync(channel, message);
1222 }
1223
1224 /// <summary>
1225 /// 发布(使用序列化)
1226 /// </summary>
1227 /// <typeparam name="T"></typeparam>
1228 /// <param name="channel"></param>
1229 /// <param name="message"></param>
1230 /// <returns></returns>
1231 public async Task<long> PublishAsync<T>(RedisChannel channel, T message)
1232 {
1233 var sub = _connMultiplexer.GetSubscriber();
1234 return await sub.PublishAsync(channel, Serialize(message));
1235 }
1236
1237 #endregion 发布订阅-async
1238
1239 #endregion 发布订阅
1240
1241 #region private method
1242
1243 /// <summary>
1244 /// 添加 Key 的前缀
1245 /// </summary>
1246 /// <param name="key"></param>
1247 /// <returns></returns>
1248 private static string AddKeyPrefix(string key)
1249 {
1250 return $"{DefaultKey}:{key}";
1251 }
1252
1253 /// <summary>
1254 /// 转换为字符串
1255 /// </summary>
1256 /// <typeparam name="T"></typeparam>
1257 /// <param name="list"></param>
1258 /// <returns></returns>
1259 private static IEnumerable<string> ConvertStrings<T>(IEnumerable<T> list) where T : struct
1260 {
1261 if (list == null) throw new ArgumentNullException(nameof(list));
1262 return list.Select(x => x.ToString());
1263 }
1264
1265 #region 注册事件
1266
1267 /// <summary>
1268 /// 添加注册事件
1269 /// </summary>
1270 private static void AddRegisterEvent()
1271 {
1272 _connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
1273 _connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
1274 _connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
1275 _connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
1276 _connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
1277 _connMultiplexer.InternalError += ConnMultiplexer_InternalError;
1278 _connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
1279 }
1280
1281 /// <summary>
1282 /// 重新配置广播时(通常意味着主从同步更改)
1283 /// </summary>
1284 /// <param name="sender"></param>
1285 /// <param name="e"></param>
1286 private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
1287 {
1288 Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
1289 }
1290
1291 /// <summary>
1292 /// 发生内部错误时(主要用于调试)
1293 /// </summary>
1294 /// <param name="sender"></param>
1295 /// <param name="e"></param>
1296 private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
1297 {
1298 Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
1299 }
1300
1301 /// <summary>
1302 /// 更改集群时
1303 /// </summary>
1304 /// <param name="sender"></param>
1305 /// <param name="e"></param>
1306 private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
1307 {
1308 Console.WriteLine(
1309 $"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
1310 }
1311
1312 /// <summary>
1313 /// 配置更改时
1314 /// </summary>
1315 /// <param name="sender"></param>
1316 /// <param name="e"></param>
1317 private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
1318 {
1319 Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
1320 }
1321
1322 /// <summary>
1323 /// 发生错误时
1324 /// </summary>
1325 /// <param name="sender"></param>
1326 /// <param name="e"></param>
1327 private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
1328 {
1329 Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
1330 }
1331
1332 /// <summary>
1333 /// 物理连接失败时
1334 /// </summary>
1335 /// <param name="sender"></param>
1336 /// <param name="e"></param>
1337 private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
1338 {
1339 Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
1340 }
1341
1342 /// <summary>
1343 /// 建立物理连接时
1344 /// </summary>
1345 /// <param name="sender"></param>
1346 /// <param name="e"></param>
1347 private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
1348 {
1349 Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
1350 }
1351
1352 #endregion 注册事件
1353
1354 /// <summary>
1355 /// 序列化
1356 /// </summary>
1357 /// <param name="obj"></param>
1358 /// <returns></returns>
1359 private static byte[] Serialize(object obj)
1360 {
1361 if (obj == null)
1362 return null;
1363
1364 var binaryFormatter = new BinaryFormatter();
1365 using (var memoryStream = new MemoryStream())
1366 {
1367 binaryFormatter.Serialize(memoryStream, obj);
1368 var data = memoryStream.ToArray();
1369 return data;
1370 }
1371 }
1372
1373 /// <summary>
1374 /// 反序列化
1375 /// </summary>
1376 /// <typeparam name="T"></typeparam>
1377 /// <param name="data"></param>
1378 /// <returns></returns>
1379 private static T Deserialize<T>(byte[] data)
1380 {
1381 if (data == null)
1382 return default(T);
1383
1384 var binaryFormatter = new BinaryFormatter();
1385 using (var memoryStream = new MemoryStream(data))
1386 {
1387 var result = (T) binaryFormatter.Deserialize(memoryStream);
1388 return result;
1389 }
1390 }
1391
1392 #endregion private method
1393 }
1394 } |
|