Redis .Net客户端源码

时间:2022-09-16 21:39:22

1、简单介绍

当前NoSql使用已经极为普遍,无论是Java生态圈,还是.net生态圈。大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面。主流的技术有:HBase、MongoDB、Redis等等。我为什么要选择Redis呢?一是因为,我跟风学来的。。。二是,套用某位大神的话,Redis是Nosql数据库中使用较为广泛的非关系型内存数据库,redis内部是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型,类似于Java中的map)。Redis基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。总之,我就是用了,而且取得了不错的性能提升,减轻了数据库服务器的压力。

我这里的项目,采用二进制压缩存储,当然你也可以选择json方式,与Redis服务器即时连接即时释放,支持高并发读写,以List、HashSet类型存储为主要结构,读写分离,可以灵活配置。

2、Redis客户端部分源码

Redis  .Net客户端源码Redis  .Net客户端源码
   1 public class RedisClient
2 {
3 public string ChannelName = string.Empty;
4
5 public bool IsPattern = false;
6
7 public Action<Exception> OnError;
8
9 public Action<object, object> OnMessage;
10
11 public Action<object[]> OnSuccess;
12
13 public Action<object> OnUnSubscribe;
14
15 #region 常用方法
16
17 private void SelectDB(TcpClient client)
18 {
19 try
20 {
21 if (client.DB != DB)
22 {
23 client.DB = DB;
24 using (var cmd = new Command())
25 {
26 cmd.Add(ConstValues.REDIS_COMMAND_SELECT);
27 cmd.Add(DB.ToString());
28 using (var result = TcpClient.Send(cmd, client))
29 {
30 }
31 }
32 }
33 }
34 catch (Exception ex)
35 {
36
37 Log.Instance.Error("堆栈内存分配不足:{0}",ex.Message);
38 }
39
40 }
41
42 #endregion
43
44 /// <summary>
45 /// 返回哈希表key中域的数量
46 /// </summary>
47 /// <param name="key"></param>
48 /// <returns>哈希表中域的数量 当key不存在时,返回0</returns>
49 public int HLen(string key)
50 {
51 using (var c = GetReader())
52 {
53 using (var cmd = new Command())
54 {
55 cmd.Add(ConstValues.REDIS_COMMAND_HLEN);
56 cmd.Add(key);
57 using (var result = TcpClient.Send(cmd, c.Client))
58 {
59 return int.Parse(result.ResultData.ToString());
60 }
61 }
62 }
63 }
64
65 /// <summary>
66 /// 为给定key设置生存时间
67 /// 当key过期时,它会被自动删除。
68 /// 在Redis中,带有生存时间的key被称作“易失的”(volatile)。
69 /// </summary>
70 /// <param name="key"></param>
71 /// <param name="time"></param>
72 /// <returns>
73 /// 设置成功返回1。
74 /// 当key不存在或者不能为key设置生存时间时(比如在低于2.1.3中你尝试更新key的生存时间),返回0。
75 /// </returns>
76 public int Expire(string key, long time)
77 {
78 using (var c = GetWriter())
79 {
80 using (var cmd = new Command())
81 {
82 cmd.Add(ConstValues.REDIS_COMMAND_EXPIRE);
83 cmd.Add(key);
84 cmd.Add(time.ToString());
85 using (var result = TcpClient.Send(cmd, c.Client))
86 {
87 return int.Parse(result.ResultData.ToString());
88 }
89 }
90 }
91 }
92
93 /// <summary>
94 /// 返回给定key的剩余生存时间(time to live)(以秒为单位)。
95 /// </summary>
96 /// <param name="key"></param>
97 /// <returns>key的剩余生存时间(以秒为单位)。当key不存在或没有设置生存时间时,返回-1 。</returns>
98 public int TTL(string key)
99 {
100 using (var c = GetReader())
101 {
102 using (var cmd = new Command())
103 {
104 cmd.Add(ConstValues.REDIS_COMMAND_TTL);
105 cmd.Add(key);
106 using (var result = TcpClient.Send(cmd, c.Client))
107 {
108 return int.Parse(result.ResultData.ToString());
109 }
110 }
111 }
112 }
113
114 /// <summary>
115 /// 返回当前服器时间
116 /// </summary>
117 /// <returns></returns>
118 public List<string> Time()
119 {
120 List<string> r;
121 using (var c = GetReader())
122 {
123 using (var cmd = new Command())
124 {
125 cmd.Add(ConstValues.REDIS_COMMAND_TIME);
126 using (var result = TcpClient.Send(cmd, c.Client))
127 {
128 r = new List<string>(result.ResultDataBlock.Count);
129 foreach (var i in result.ResultDataBlock)
130 {
131 r.Add(i.GetString());
132 }
133 }
134 }
135 }
136 return r;
137 }
138
139 /// <summary>
140 /// 从当前数据库中随机返回(不删除)一个key。
141 /// </summary>
142 /// <typeparam name="T"></typeparam>
143 /// <returns>当数据库不为空时,返回一个key。当数据库为空时,返回nil。</returns>
144 public T RandomKey<T>()
145 {
146 T t;
147 using (var c = GetReader())
148 {
149 using (var cmd = new Command())
150 {
151 cmd.Add(ConstValues.REDIS_COMMAND_RANDOMKEY);
152 using (var result = TcpClient.Send(cmd, c.Client))
153 {
154 t = (T)FromRedis(result.ResultDataBlock[0], DataType.String, typeof(T));
155 }
156 }
157 }
158 return t;
159 }
160
161 public void Delete(IList<string> keys)
162 {
163 Delete(keys.ToArray());
164 }
165
166 /// <summary>
167 /// 查找符合给定模式的key。
168 /// </summary>
169 /// <param name="match"></param>
170 /// <returns>符合给定模式的key列表。</returns>
171 [Obsolete("KEYS的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(Set)。")]
172 public List<string> Keys(string match)
173 {
174 List<string> r;
175 using (var c = GetReader())
176 {
177 using (var cmd = new Command())
178 {
179 cmd.Add(ConstValues.REDIS_COMMAND_KEYS);
180 cmd.Add(match);
181 using (var result = TcpClient.Send(cmd, c.Client))
182 {
183 r = new List<string>(result.ResultDataBlock.Count);
184 foreach (var i in result.ResultDataBlock)
185 {
186 r.Add(i.GetString());
187 }
188 }
189 }
190 }
191 return r;
192 }
193
194 /// <summary>
195 /// 返回列表key的长度。
196 /// </summary>
197 /// <param name="key"></param>
198 /// <returns>列表key的长度。</returns>
199 public int ListLength(string key)
200 {
201 using (var c = GetReader())
202 {
203 using (var cmd = new Command())
204 {
205 cmd.Add(ConstValues.REDIS_COMMAND_LLEN);
206 cmd.Add(key);
207 using (var result = TcpClient.Send(cmd, c.Client))
208 {
209 return int.Parse(result.ResultData.ToString());
210 }
211 }
212 }
213 }
214
215 /// <summary>
216 /// 移除并返回列表key的头元素
217 /// </summary>
218 /// <typeparam name="T"></typeparam>
219 /// <param name="key"></param>
220 /// <param name="dtype"></param>
221 /// <returns>列表的头元素</returns>
222 public T LPop<T>(string key, DataType dtype)
223 {
224 using (var c = GetWriter())
225 {
226 using (var cmd = new Command())
227 {
228 cmd.Add(ConstValues.REDIS_COMMAND_LPOP);
229 cmd.Add(key);
230 using (var result = TcpClient.Send(cmd, c.Client))
231 {
232 return (T)FromRedis(result.ResultDataBlock[0], dtype, typeof(T));
233 }
234 }
235 }
236 }
237
238 /// <summary>
239 /// 移除并返回列表key的尾元素
240 /// </summary>
241 /// <typeparam name="T"></typeparam>
242 /// <param name="key"></param>
243 /// <param name="dtype"></param>
244 /// <returns>列表的尾元素。</returns>
245 public T RPOP<T>(string key, DataType dtype)
246 {
247 using (var c = GetWriter())
248 {
249 using (var cmd = new Command())
250 {
251 cmd.Add(ConstValues.REDIS_COMMAND_RPOP);
252 cmd.Add(key);
253 using (var result = TcpClient.Send(cmd, c.Client))
254 {
255 return (T)FromRedis(result.ResultDataBlock[0], dtype, typeof(T));
256 }
257 }
258 }
259 }
260
261 /// <summary>
262 /// 将一个或多个值value插入到列表key的表头
263 /// </summary>
264 /// <param name="key"></param>
265 /// <param name="value"></param>
266 /// <param name="dtype"></param>
267 /// <returns>执行LPUSH命令后,列表的长度</returns>
268 public int LPUSH(string key, object value, DataType dtype)
269 {
270 using (var c = GetWriter())
271 {
272 using (var cmd = new Command())
273 {
274 cmd.Add(ConstValues.REDIS_COMMAND_LPUSH);
275 cmd.Add(key);
276 ToRedis(value, dtype, cmd);
277 using (var result = TcpClient.Send(cmd, c.Client))
278 {
279 return int.Parse(result.ResultData.ToString());
280 }
281 }
282 }
283 }
284
285 /// <summary>
286 /// 将列表key下标为index的元素的值设置为value。
287 /// </summary>
288 /// <param name="key"></param>
289 /// <param name="index"></param>
290 /// <param name="value"></param>
291 /// <param name="dtype"></param>
292 /// <returns>操作成功返回ok,否则返回错误信息。</returns>
293 public string SetListItem(string key, int index, object value, DataType dtype)
294 {
295 using (var c = GetWriter())
296 {
297 using (var cmd = new Command())
298 {
299 cmd.Add(ConstValues.REDIS_COMMAND_LSET);
300 cmd.Add(key);
301 cmd.Add(index.ToString());
302 ToRedis(value, dtype, cmd);
303 using (var result = TcpClient.Send(cmd, c.Client))
304 {
305 return result.ResultData.ToString();
306 }
307 }
308 }
309 }
310
311 /// <summary>
312 /// 将一个或多个值value插入到列表key的表尾。
313 /// </summary>
314 /// <param name="key"></param>
315 /// <param name="value"></param>
316 /// <param name="dtype"></param>
317 /// <returns></returns>
318 public int RPush(string key, object value, DataType dtype)
319 {
320 using (var c = GetWriter())
321 {
322 using (var cmd = new Command())
323 {
324 cmd.Add(ConstValues.REDIS_COMMAND_RPUSH);
325 cmd.Add(key);
326 ToRedis(value, dtype, cmd);
327 using (var result = TcpClient.Send(cmd, c.Client))
328 {
329 return int.Parse(result.ResultData.ToString());
330 }
331 }
332 }
333 }
334
335 /// <summary>
336 /// 返回列表key中指定区间内的元素,区间以偏移量start和stop指定。
337 /// </summary>
338 /// <typeparam name="T"></typeparam>
339 /// <param name="key"></param>
340 /// <param name="start"></param>
341 /// <param name="end"></param>
342 /// <param name="dtype"></param>
343 /// <returns></returns>
344 public IList<T> ListRange<T>(string key, int start, int end, DataType dtype)
345 {
346 //string cachekey = $"{key}_list_{start}_{end}";
347 using (var c = GetReader())
348 {
349 IList<T> lst = new List<T>();
350 using (var cmd = new Command())
351 {
352 cmd.Add(ConstValues.REDIS_COMMAND_LRANGE);
353 cmd.Add(key);
354 cmd.Add(start.ToString());
355 cmd.Add(end.ToString());
356 using (var result = TcpClient.Send(cmd, c.Client))
357 {
358 foreach (var item in result.ResultDataBlock)
359 {
360 lst.Add((T)FromRedis(item, dtype, typeof(T)));
361 }
362 }
363 }
364 return lst;
365 }
366 }
367
368 /// <summary>
369 /// 返回列表key中指定区间内的元素,区间以偏移量start和stop指定。
370 /// </summary>
371 /// <typeparam name="T"></typeparam>
372 /// <param name="key"></param>
373 /// <param name="dtype"></param>
374 /// <returns></returns>
375 public IList<T> ListRange<T>(string key, DataType dtype)
376 {
377 return ListRange<T>(key, 0, -1, dtype);
378 }
379
380 /// <summary>
381 /// 返回列表key中,下标为index的元素。
382 /// </summary>
383 /// <typeparam name="T"></typeparam>
384 /// <param name="key"></param>
385 /// <param name="index"></param>
386 /// <param name="dtype"></param>
387 /// <returns></returns>
388 public T GetListItem<T>(string key, int index, DataType dtype)
389 {
390 using (var c = GetReader())
391 {
392 using (var cmd = new Command())
393 {
394 cmd.Add(ConstValues.REDIS_COMMAND_LINDEX);
395 cmd.Add(key);
396 cmd.Add(index.ToString());
397 using (var result = TcpClient.Send(cmd, c.Client))
398 {
399 return (T)FromRedis(result.ResultDataBlock[0], dtype, typeof(T));
400 }
401 }
402 }
403 }
404
405 /// <summary>
406 /// 返回哈希表key中,一个或多个给定域的值。
407 /// </summary>
408 /// <typeparam name="T"></typeparam>
409 /// <param name="key"></param>
410 /// <param name="fields"></param>
411 /// <param name="type"></param>
412 /// <returns>一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。</returns>
413 public IList<T> HashGetFields<T>(string key, NameType[] fields, DataType type)
414 {
415 var result = GetResultSpace<T>(fields.Length);
416 NameType item;
417 using (var c = GetReader())
418 {
419 var inputs = new List<NameType>();
420 using (var cmd = new Command())
421 {
422 cmd.Add(ConstValues.REDIS_COMMAND_HMGET);
423 cmd.Add(key);
424 for (var i = 0; i < fields.Length; i++)
425 {
426 item = fields[i];
427 inputs.Add(item);
428 item.Index = i;
429 cmd.Add(item.Name);
430 }
431 using (var r = TcpClient.Send(cmd, c.Client))
432 {
433 for (var i = 0; i < inputs.Count; i++)
434 {
435 item = inputs[i];
436 result[item.Index] = (T)FromRedis(r.ResultDataBlock[i], type, typeof(T));
437 }
438 }
439 }
440 }
441 return result;
442 }
443
444 /// <summary>
445 /// 返回哈希表key中给定域field的值。
446 /// </summary>
447 /// <typeparam name="T"></typeparam>
448 /// <param name="key"></param>
449 /// <param name="name"></param>
450 /// <param name="type"></param>
451 /// <returns>给定域的值。</returns>
452 public T HashGet<T>(string key, string name, DataType type)
453 {
454 T t;
455 using (var c = GetReader())
456 {
457 using (var cmd = new Command())
458 {
459 cmd.Add(ConstValues.REDIS_COMMAND_HGET);
460 cmd.Add(key);
461 cmd.Add(name);
462 using (var r = TcpClient.Send(cmd, c.Client))
463 {
464 if (r.ResultDataBlock != null && r.ResultDataBlock.Any())
465 {
466 t = (T)FromRedis(r.ResultDataBlock[0], type, typeof(T));
467 }
468 else
469 {
470 t = default(T);
471 }
472 }
473 }
474 }
475 return t;
476 }
477
478
479 /// <summary>
480 /// 返回哈希表key中,所有的域和值。
481 /// </summary>
482 /// <typeparam name="T"></typeparam>
483 /// <param name="key"></param>
484 /// <param name="type"></param>
485 /// <returns>以列表形式返回哈希表的域和域的值。 若key不存在,返回空列表。</returns>
486 public List<Field> HashGetAll<T>(string key, DataType type)
487 {
488 var result = new List<Field>();
489 var k = "";
490 using (var c = GetReader())
491 {
492 //var inputs = new List<NameType>();
493 using (var cmd = new Command())
494 {
495 cmd.Add(ConstValues.REDIS_COMMAND_HGETALL);
496 cmd.Add(key);
497 using (var r = TcpClient.Send(cmd, c.Client))
498 {
499 if (r.ResultDataBlock.Count > 0)
500 for (var i = 0; i < r.ResultDataBlock.Count; i++)
501 {
502 if (i % 2 == 0)
503 k = (string)FromRedis(r.ResultDataBlock[i], DataType.String, Type.GetType(k));
504 else
505 {
506 var value = FromRedis(r.ResultDataBlock[i], type, typeof(T));
507 var item = new Field { Name = k, Value = value };
508 result.Add(item);
509 }
510 }
511 }
512 }
513 }
514 return result;
515 }
516
517 /// <summary>
518 /// 检查给定key是否存在。
519 /// </summary>
520 /// <param name="key"></param>
521 /// <returns>若key存在,返回1,否则返回0。</returns>
522 public int Exists(string key)
523 {
524 using (var c = GetReader())
525 {
526 using (var cmd = new Command())
527 {
528 cmd.Add(ConstValues.REDIS_COMMAND_EXISTS);
529 cmd.Add(key);
530 using (var result = TcpClient.Send(cmd, c.Client))
531 {
532 if (result.ResultData != null)
533 {
534 return int.Parse(result.ResultData.ToString());
535 }
536 }
537 }
538 }
539 return 0;
540 }
541
542 /// <summary>
543 /// 查看哈希表key中,给定域field是否存在。
544 /// </summary>
545 /// <param name="key"></param>
546 /// <param name="field"></param>
547 /// <param name="type"></param>
548 /// <returns>
549 /// 如果哈希表含有给定域,返回1。
550 /// 如果哈希表不含有给定域,或key不存在,返回0。
551 /// </returns>
552 public int HashFieldExists(string key, string field, DataType type)
553 {
554 using (var c = GetReader())
555 {
556 using (var cmd = new Command())
557 {
558 cmd.Add(ConstValues.REDIS_COMMAND_HEXISTS);
559 cmd.Add(key);
560 cmd.Add(field);
561 using (var result = TcpClient.Send(cmd, c.Client))
562 {
563 if (result.ResultData != null)
564 {
565 return int.Parse(result.ResultData.ToString());
566 }
567 }
568 }
569 }
570 return 0;
571 }
572
573 /// <summary>
574 /// 返回哈希表key中的所有域。
575 /// </summary>
576 /// <param name="key"></param>
577 /// <param name="type"></param>
578 /// <returns></returns>
579 public List<string> HashGetAllFields(string key, DataType type)
580 {
581 var result = new List<string>();
582 using (var c = GetReader())
583 {
584 using (var cmd = new Command())
585 {
586 cmd.Add(ConstValues.REDIS_COMMAND_HKEYS);
587 cmd.Add(key);
588 using (var r = TcpClient.Send(cmd, c.Client))
589 {
590 if (r.ResultDataBlock.Count > 0)
591 {
592 result.AddRange(r.ResultDataBlock.Select(t => (string)FromRedis(t, type, typeof(string))));
593 }
594 }
595 }
596 }
597 return result;
598 }
599 /// <summary>
600 /// 返回哈希表key中的所有值(key-T)
601 /// </summary>
602 /// <typeparam name="T"></typeparam>
603 /// <param name="key"></param>
604 /// <param name="type"></param>
605 /// <returns></returns>
606 public List<T> HashGetAllValues<T>(string key, DataType type)
607 {
608 var result = new List<T>();
609 using (var c = GetReader())
610 {
611 using (var cmd = new Command())
612 {
613 cmd.Add(ConstValues.REDIS_COMMAND_HVALS);
614 cmd.Add(key);
615 using (var r = TcpClient.Send(cmd, c.Client))
616 {
617 if (r.ResultDataBlock?.Count > 0)
618 {
619 result.AddRange(r.ResultDataBlock.Select(t => (T)FromRedis(t, type, typeof(T))));
620 }
621 }
622 }
623 }
624 return result;
625 }
626 /// <summary>
627 /// 返回哈希表key中的所有值(key-List<T>
628 /// </summary>
629 /// <typeparam name="T"></typeparam>
630 /// <param name="key"></param>
631 /// <param name="type"></param>
632 /// <returns></returns>
633 public List<T> HashGetAllValuesT<T>(string key, DataType type)
634 {
635 var result = new List<T>();
636 using (var c = GetReader())
637 {
638 using (var cmd = new Command())
639 {
640 cmd.Add(ConstValues.REDIS_COMMAND_HVALS);
641 cmd.Add(key);
642 using (var r = TcpClient.Send(cmd, c.Client))
643 {
644 if (r.ResultDataBlock.Count > 0)
645 {
646 foreach (var x in r.ResultDataBlock)
647 {
648 var re= (List<T>) FromRedis(x, type, typeof (List<T>));
649 if(re!=null)result.AddRange(re);
650 }
651 // result.AddRange(r.ResultDataBlock.Select(t => (List<T>)FromRedis(t, type, typeof(List<T>))));
652 }
653 }
654 }
655 }
656 return result;
657 }
658
659 /// <summary>
660 /// 返回所有(一个或多个)给定key的值。
661 /// </summary>
662 /// <typeparam name="T"></typeparam>
663 /// <typeparam name="T1"></typeparam>
664 /// <param name="key"></param>
665 /// <param name="key1"></param>
666 /// <param name="type"></param>
667 /// <returns></returns>
668 public IList<object> Get<T, T1>(string key, string key1, DataType type)
669 {
670 return Get(new[] { typeof(T), typeof(T1) }, new[] { key, key1 }, type);
671 }
672
673 /// <summary>
674 /// 返回所有(一个或多个)给定key的值。
675 /// </summary>
676 /// <typeparam name="T"></typeparam>
677 /// <typeparam name="T1"></typeparam>
678 /// <typeparam name="T2"></typeparam>
679 /// <param name="key"></param>
680 /// <param name="key1"></param>
681 /// <param name="key2"></param>
682 /// <param name="type"></param>
683 /// <returns></returns>
684 public IList<object> Get<T, T1, T2>(string key, string key1, string key2, DataType type)
685 {
686 return Get(new[] { typeof(T), typeof(T1), typeof(T2) }, new[] { key, key1, key2 }, type);
687 }
688
689 /// <summary>
690 /// 返回所有(一个或多个)给定key的值。
691 /// </summary>
692 /// <typeparam name="T"></typeparam>
693 /// <typeparam name="T1"></typeparam>
694 /// <typeparam name="T2"></typeparam>
695 /// <typeparam name="T3"></typeparam>
696 /// <param name="key"></param>
697 /// <param name="key1"></param>
698 /// <param name="key2"></param>
699 /// <param name="key3"></param>
700 /// <param name="type"></param>
701 /// <returns></returns>
702 public IList<object> Get<T, T1, T2, T3>(string key, string key1, string key2, string key3, DataType type)
703 {
704 return Get(new[] { typeof(T), typeof(T1), typeof(T2), typeof(T3) },
705 new[] { key, key1, key2, key3 }, type);
706 }
707
708 /// <summary>
709 /// 返回所有(一个或多个)给定key的值。
710 /// </summary>
711 /// <typeparam name="T"></typeparam>
712 /// <typeparam name="T1"></typeparam>
713 /// <typeparam name="T2"></typeparam>
714 /// <typeparam name="T3"></typeparam>
715 /// <typeparam name="T4"></typeparam>
716 /// <param name="key"></param>
717 /// <param name="key1"></param>
718 /// <param name="key2"></param>
719 /// <param name="key3"></param>
720 /// <param name="key4"></param>
721 /// <param name="type"></param>
722 /// <returns></returns>
723 public IList<object> Get<T, T1, T2, T3, T4>(string key, string key1, string key2, string key3, string key4,
724 DataType type)
725 {
726 return Get(new[] { typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4) },
727 new[] { key, key1, key2, key3, key4 }, type);
728 }
729
730 /// <summary>
731 /// 返回所有(一个或多个)给定key的值。
732 /// </summary>
733 /// <param name="types"></param>
734 /// <param name="keys"></param>
735 /// <param name="dtype"></param>
736 /// <returns></returns>
737 public IList<object> Get(Type[] types, string[] keys, DataType dtype)
738 {
739 using (var c = GetReader())
740 {
741 var result = GetResultSpace<object>(keys.Length);
742 var _types = new List<NameType>();
743 using (var cmd = new Command())
744 {
745 cmd.Add(ConstValues.REDIS_COMMAND_MGET);
746 for (var i = 0; i < keys.Length; i++)
747 {
748 var key = keys[i];
749 cmd.Add(key);
750 _types.Add(new NameType(keys[i], i));
751 }
752 using (var r = TcpClient.Send(cmd, c.Client))
753 {
754 for (var i = 0; i < _types.Count; i++)
755 {
756 var item = FromRedis(r.ResultDataBlock[i], dtype, null);
757 result[_types[i].Index] = item;
758 }
759 }
760 }
761 return result;
762 }
763 }
764
765 private List<T> GetResultSpace<T>(int count)
766 {
767 var result = new List<T>(count);
768 for (var i = 0; i < count; i++)
769 {
770 result.Add(default(T));
771 }
772 return result;
773 }
774
775 /// <summary>
776 /// 返回key所关联的字符串值
777 /// </summary>
778 /// <param name="key"></param>
779 /// <returns></returns>
780 public string Get(string key)
781 {
782 return Get<string>(key, DataType.String);
783 }
784
785 /// <summary>
786 /// 返回key所关联的字符串值
787 /// </summary>
788 /// <typeparam name="T"></typeparam>
789 /// <param name="key"></param>
790 /// <param name="type"></param>
791 /// <returns></returns>
792 public T Get<T>(string key, DataType type)
793 {
794 using (var c = GetReader())
795 {
796 using (var cmd = new Command())
797 {
798 cmd.Add(ConstValues.REDIS_COMMAND_GET);
799 cmd.Add(key);
800 using (var result = TcpClient.Send(cmd, c.Client))
801 {
802 if (result.ResultDataBlock.Count > 0)
803 {
804 var value = (T)FromRedis(result.ResultDataBlock[0], type, typeof(T));
805 return value;
806 }
807 }
808 }
809 return default(T);
810 }
811 }
812
813 /// <summary>
814 /// 将给定key的值设为value,并返回key的旧值。
815 /// </summary>
816 /// <param name="key"></param>
817 /// <param name="value"></param>
818 /// <returns></returns>
819 public string GetSet(string key, object value)
820 {
821 return GetSet<string>(key, value, DataType.String);
822 }
823
824 /// <summary>
825 /// 将给定key的值设为value,并返回key的旧值。
826 /// </summary>
827 /// <typeparam name="T"></typeparam>
828 /// <param name="key"></param>
829 /// <param name="value"></param>
830 /// <param name="type"></param>
831 /// <returns></returns>
832 public T GetSet<T>(string key, object value, DataType type)
833 {
834 using (var c = GetWriter())
835 {
836 using (var cmd = new Command())
837 {
838 cmd.Add(ConstValues.REDIS_COMMAND_GETSET);
839 cmd.Add(key);
840
841 ToRedis(value, type, cmd);
842
843 using (var result = TcpClient.Send(cmd, c.Client))
844 {
845 if (result.ResultDataBlock.Count > 0)
846 {
847 var oldvalue = (T)FromRedis(result.ResultDataBlock[0], type, typeof(T));
848 return oldvalue;
849 }
850 }
851 }
852 return default(T);
853 }
854 }
855
856 /// <summary>
857 /// 同时将多个field - value(域-值)对设置到哈希表key中。
858 /// </summary>
859 /// <param name="key"></param>
860 /// <param name="name"></param>
861 /// <param name="value"></param>
862 /// <param name="type"></param>
863 /// <returns></returns>
864 public string SetFields(string key, string name, object value, DataType type)
865 {
866 using (var c = GetWriter())
867 {
868 using (var cmd = new Command())
869 {
870 cmd.Add(ConstValues.REDIS_COMMAND_HMSET);
871 cmd.Add(key);
872 cmd.Add(name);
873 ToRedis(value, type, cmd);
874 using (var result = TcpClient.Send(cmd, c.Client))
875 {
876 return result.ResultData.ToString();
877 }
878 }
879 }
880 }
881
882 /// <summary>
883 /// 将哈希表key中的域field的值设为value。
884 /// </summary>
885 /// <param name="key"></param>
886 /// <param name="field"></param>
887 /// <param name="value"></param>
888 /// <param name="type"></param>
889 /// <returns></returns>
890 public int HashSetFieldValue(string key, string field, object value, DataType type)
891 {
892 try
893 {
894 using (var c = GetWriter())
895 {
896 using (var cmd = new Command())
897 {
898 cmd.Add(ConstValues.REDIS_COMMAND_HSET);
899 cmd.Add(key);
900 cmd.Add(field);
901 ToRedis(value, type, cmd);
902 using (var result = TcpClient.Send(cmd, c.Client))
903 {
904 return int.Parse(result.ResultData.ToString());
905 }
906 }
907 }
908 }
909 catch (Exception ex)
910 {
911
912 throw;
913 }
914
915 }
916
917 /// <summary>
918 /// 将哈希表key中的域field的值设置为value,当且仅当域field不存在。
919 /// </summary>
920 /// <param name="key"></param>
921 /// <param name="item"></param>
922 /// <param name="type"></param>
923 /// <returns>设置成功,返回1。如果给定域已经存在且没有操作被执行,返回0。</returns>
924 public int HashSetFieldValueNx(string key, Field item, DataType type)
925 {
926 using (var c = GetWriter())
927 {
928 using (var cmd = new Command())
929 {
930 cmd.Add(ConstValues.REDIS_COMMAND_HSETNX);
931 cmd.Add(key);
932 cmd.Add(item.Name);
933 ToRedis(item.Value, type, cmd);
934 using (var result = TcpClient.Send(cmd, c.Client))
935 {
936 return int.Parse(result.ResultData.ToString());
937 }
938 }
939 }
940 }
941
942 /// <summary>
943 /// 同时设置一个或多个key-value对。
944 /// </summary>
945 /// <param name="kValues"></param>
946 /// <param name="dtype"></param>
947 public void MSet(Field[] kValues, DataType dtype)
948 {
949 using (var c = GetWriter())
950 {
951 using (var cmd = new Command())
952 {
953 cmd.Add(ConstValues.REDIS_COMMAND_MSET);
954 foreach (var item in kValues)
955 {
956 cmd.Add(item.Name);
957 ToRedis(item.Value, dtype, cmd);
958 }
959 using (TcpClient.Send(cmd, c.Client))
960 {
961 }
962 }
963 }
964 }
965
966 /// <summary>
967 /// 将key中储存的数字值增一。
968 /// </summary>
969 /// <param name="key"></param>
970 /// <returns></returns>
971 public int Incr(string key)
972 {
973 using (var c = GetWriter())
974 {
975 using (var cmd = new Command())
976 {
977 cmd.Add(ConstValues.REDIS_COMMAND_INCR);
978 cmd.Add(key);
979 using (var result = TcpClient.Send(cmd, c.Client))
980 {
981 if (result.ResultData != null)
982 {
983 return int.Parse(result.ResultData.ToString());
984 }
985 }
986 }
987 }
988 return 0;
989 }
990
991 /// <summary>
992 /// 将key所储存的值加上增量increment。
993 /// </summary>
994 /// <param name="key"></param>
995 /// <param name="increment"></param>
996 /// <returns></returns>
997 public long Incrby(string key, long increment)
998 {
999 using (var c = GetWriter())
1000 {
1001 using (var cmd = new Command())
1002 {
1003 cmd.Add(ConstValues.REDIS_COMMAND_INCRBY);
1004 cmd.Add(key);
1005 cmd.Add(increment.ToString());
1006 using (var result = TcpClient.Send(cmd, c.Client))
1007 {
1008 if (result.ResultData != null)
1009 {
1010 return long.Parse(result.ResultData.ToString());
1011 }
1012 }
1013 }
1014 }
1015 return 0;
1016 }
1017
1018 /// <summary>
1019 /// 将key中储存的数字值减一。
1020 /// </summary>
1021 /// <param name="key"></param>
1022 /// <returns></returns>
1023 public int Decr(string key)
1024 {
1025 using (var c = GetWriter())
1026 {
1027 using (var cmd = new Command())
1028 {
1029 cmd.Add(ConstValues.REDIS_COMMAND_DECR);
1030 cmd.Add(key);
1031 using (var result = TcpClient.Send(cmd, c.Client))
1032 {
1033 if (result.ResultData != null)
1034 {
1035 return int.Parse(result.ResultData.ToString());
1036 }
1037 }
1038 }
1039 }
1040 return 0;
1041 }
1042
1043 /// <summary>
1044 /// 将key所储存的值减去减量decrement。
1045 /// </summary>
1046 /// <param name="key"></param>
1047 /// <param name="decrement"></param>
1048 /// <returns></returns>
1049 public long DecrBy(string key, long decrement)
1050 {
1051 using (var c = GetWriter())
1052 {
1053 using (var cmd = new Command())
1054 {
1055 cmd.Add(ConstValues.REDIS_COMMAND_DECRBY);
1056 cmd.Add(key);
1057 cmd.Add(decrement.ToString());
1058 using (var result = TcpClient.Send(cmd, c.Client))
1059 {
1060 if (result.ResultData != null)
1061 {
1062 return long.Parse(result.ResultData.ToString());
1063 }
1064 }
1065 }
1066 }
1067 return 0;
1068 }
1069
1070 /// <summary>
1071 /// 将字符串值value关联到key。
1072 /// </summary>
1073 /// <param name="key"></param>
1074 /// <param name="value"></param>
1075 /// <param name="type"></param>
1076 public void Set(string key, object value, DataType type)
1077 {
1078 using (var c = GetWriter())
1079 {
1080 using (var cmd = new Command())
1081 {
1082 cmd.Add(ConstValues.REDIS_COMMAND_SET);
1083 cmd.Add(key);
1084
1085 ToRedis(value, type, cmd);
1086 using (TcpClient.Send(cmd, c.Client))
1087 {
1088 }
1089 }
1090 }
1091 }
1092
1093 /// <summary>
1094 /// 将字符串值value关联到key。
1095 /// </summary>
1096 /// <param name="key"></param>
1097 /// <param name="value"></param>
1098 /// <param name="seconds"></param>
1099 /// <param name="milliseconds"></param>
1100 /// <param name="existSet"></param>
1101 /// <param name="type"></param>
1102 public void Set(string key, object value, long? seconds, long? milliseconds, bool? existSet, DataType type)
1103 {
1104 using (var c = GetWriter())
1105 {
1106 using (var cmd = new Command())
1107 {
1108 cmd.Add(ConstValues.REDIS_COMMAND_SET);
1109 cmd.Add(key);
1110 ToRedis(value, type, cmd);
1111 if (seconds != null && seconds > 0)
1112 {
1113 cmd.Add("EX");
1114 cmd.Add(seconds.ToString());
1115 }
1116 if (milliseconds != null && milliseconds > 0)
1117 {
1118 cmd.Add("PX");
1119 cmd.Add(milliseconds.ToString());
1120 }
1121 if (existSet != null)
1122 cmd.Add(Convert.ToBoolean(existSet) ? "XX" : "NX");
1123 using (TcpClient.Send(cmd, c.Client))
1124 {
1125 }
1126 }
1127 }
1128 }
1129
1130 /// <summary>
1131 /// 将key改名为newkey。
1132 /// </summary>
1133 /// <param name="key"></param>
1134 /// <param name="value"></param>
1135 /// <param name="type"></param>
1136 /// <returns></returns>
1137 public bool Rename(string key, object value, DataType type)
1138 {
1139 using (var c = GetWriter())
1140 {
1141 using (var cmd = new Command())
1142 {
1143 cmd.Add(ConstValues.REDIS_COMMAND_RENAME);
1144 cmd.Add(key);
1145
1146 ToRedis(value, type, cmd);
1147 using (var result = TcpClient.Send(cmd, c.Client))
1148 {
1149 if (result.ResultData != null)
1150 {
1151 return result.ResultData.ToString().Contains("OK");
1152 }
1153 }
1154 }
1155 }
1156 return false;
1157 }
1158
1159 /// <summary>
1160 /// 将一个或多个member元素及其score值加入到有序集key当中。
1161 /// </summary>
1162 /// <param name="key"></param>
1163 /// <param name="sorts"></param>
1164 /// <param name="dtype"></param>
1165 /// <returns>被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。</returns>
1166 public int Zadd(string key, IEnumerable<SortField> sorts, DataType dtype)
1167 {
1168 using (var c = GetWriter())
1169 {
1170 using (var cmd = new Command())
1171 {
1172 cmd.Add(ConstValues.REDIS_COMMAND_ZADD);
1173 cmd.Add(key);
1174 foreach (var item in sorts)
1175 {
1176 cmd.Add(item.Name.ToString());
1177 ToRedis(item.Value, dtype, cmd);
1178 }
1179 using (var result = TcpClient.Send(cmd, c.Client))
1180 {
1181 if (result.ResultData != null)
1182 {
1183 return int.Parse(result.ResultData.ToString());
1184 }
1185 }
1186 }
1187 }
1188 return 0;
1189 }
1190
1191 /// <summary>
1192 /// 返回有序集key的基数。
1193 /// </summary>
1194 /// <param name="key"></param>
1195 /// <returns></returns>
1196 public int Zcard(string key)
1197 {
1198 using (var c = GetReader())
1199 {
1200 using (var cmd = new Command())
1201 {
1202 cmd.Add(ConstValues.REDIS_COMMAND_ZCARD);
1203 cmd.Add(key);
1204 using (var result = TcpClient.Send(cmd, c.Client))
1205 {
1206 if (result.ResultData != null)
1207 {
1208 return int.Parse(result.ResultData.ToString());
1209 }
1210 }
1211 }
1212 }
1213 return 0;
1214 }
1215
1216 /// <summary>
1217 /// 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。
1218 /// </summary>
1219 /// <param name="key"></param>
1220 /// <param name="min"></param>
1221 /// <param name="max"></param>
1222 /// <returns></returns>
1223 public int Zcount(string key, int min, int max)
1224 {
1225 using (var c = GetReader())
1226 {
1227 using (var cmd = new Command())
1228 {
1229 cmd.Add(ConstValues.REDIS_COMMAND_ZCOUNT);
1230 cmd.Add(key);
1231 cmd.Add(min.ToString());
1232 cmd.Add(max.ToString());
1233 using (var result = TcpClient.Send(cmd, c.Client))
1234 {
1235 if (result.ResultData != null)
1236 {
1237 return int.Parse(result.ResultData.ToString());
1238 }
1239 }
1240 }
1241 }
1242 return 0;
1243 }
1244
1245 /// <summary>
1246 /// 返回有序集key中,指定区间内的成员。
1247 /// </summary>
1248 /// <param name="key"></param>
1249 /// <param name="start"></param>
1250 /// <param name="stop"></param>
1251 /// <param name="type"></param>
1252 /// <returns></returns>
1253 public HashSet<string> Zrange(string key, int start, int stop, DataType type)
1254 {
1255 HashSet<string> sets = null;
1256 var value = "";
1257 using (var c = GetReader())
1258 {
1259 using (var cmd = new Command())
1260 {
1261 cmd.Add(ConstValues.REDIS_COMMAND_ZRANGE);
1262 cmd.Add(key);
1263 cmd.Add(start.ToString());
1264 cmd.Add(stop.ToString());
1265 using (var result = TcpClient.Send(cmd, c.Client))
1266 {
1267 if (result.ResultDataBlock.Count > 0)
1268 {
1269 sets = new HashSet<string>();
1270 foreach (var currentdata in result.ResultDataBlock)
1271 {
1272 value = (string)FromRedis(currentdata, type, Type.GetType(value));
1273 sets.Add(value);
1274 }
1275 }
1276 }
1277 }
1278 }
1279 return sets;
1280 }
1281
1282 /// <summary>
1283 /// 返回有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。有序集成员按score值递增(从小到大)次序排列。
1284 /// </summary>
1285 /// <typeparam name="T"></typeparam>
1286 /// <param name="key"></param>
1287 /// <param name="min"></param>
1288 /// <param name="isIncludemin"></param>
1289 /// <param name="max"></param>
1290 /// <param name="isIncludemax"></param>
1291 /// <param name="type"></param>
1292 /// <returns></returns>
1293 public HashSet<T> ZrangeByScore<T>(string key, long min, bool isIncludemin, int max, bool isIncludemax,
1294 DataType type)
1295 {
1296 var hashSet = new HashSet<T>();
1297 using (var c = GetReader())
1298 {
1299 using (var cmd = new Command())
1300 {
1301 cmd.Add(ConstValues.REDIS_COMMAND_ZRANGEBYSCORE);
1302 cmd.Add(key);
1303 cmd.Add(isIncludemin ? "" : "(" + min);
1304 cmd.Add(isIncludemax ? "" : "(" + max);
1305 using (var result = TcpClient.Send(cmd, c.Client))
1306 {
1307 if (result.ResultDataBlock.Count > 0)
1308 {
1309 foreach (var currentdata in result.ResultDataBlock)
1310 {
1311 var value = (T)FromRedis(currentdata, type, typeof(T));
1312 hashSet.Add(value);
1313 }
1314 }
1315 }
1316 }
1317 }
1318 return hashSet;
1319 }
1320
1321 /// <summary>
1322 /// 返回有序集key中,指定区间内的成员。
1323 /// </summary>
1324 /// <param name="key"></param>
1325 /// <param name="start"></param>
1326 /// <param name="stop"></param>
1327 /// <param name="type"></param>
1328 /// <returns></returns>
1329 public HashSet<string> Zrevrange(string key, int start, int stop, DataType type)
1330 {
1331 HashSet<string> sets = null;
1332 var value = "";
1333 using (var c = GetReader())
1334 {
1335 using (var cmd = new Command())
1336 {
1337 cmd.Add(ConstValues.REDIS_COMMAND_ZREVRANGE);
1338 cmd.Add(key);
1339 cmd.Add(start.ToString());
1340 cmd.Add(stop.ToString());
1341 using (var result = TcpClient.Send(cmd, c.Client))
1342 {
1343 if (result.ResultDataBlock.Count > 0)
1344 {
1345 sets = new HashSet<string>();
1346 foreach (var currentdata in result.ResultDataBlock)
1347 {
1348 value = (string)FromRedis(currentdata, type, Type.GetType(value));
1349 sets.Add(value);
1350 }
1351 }
1352 }
1353 }
1354 }
1355 return sets;
1356 }
1357
1358 /// <summary>
1359 /// 返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。
1360 /// </summary>
1361 /// <param name="key"></param>
1362 /// <param name="member"></param>
1363 /// <returns></returns>
1364 public int Zrank(string key, string member)
1365 {
1366 using (var c = GetReader())
1367 {
1368 using (var cmd = new Command())
1369 {
1370 cmd.Add(ConstValues.REDIS_COMMAND_ZRANK);
1371 cmd.Add(key);
1372 cmd.Add(member);
1373 using (var result = TcpClient.Send(cmd, c.Client))
1374 {
1375 if (result.ResultData != null)
1376 {
1377 return int.Parse(result.ResultData.ToString());
1378 }
1379 }
1380 }
1381 }
1382 return 0;
1383 }
1384
1385 /// <summary>
1386 /// 返回有序集key中成员member的排名。其中有序集成员按score值递减(从大到小)排序。
1387 /// </summary>
1388 /// <param name="key"></param>
1389 /// <param name="member"></param>
1390 /// <returns></returns>
1391 public int Zrevrank(string key, string member)
1392 {
1393 using (var c = GetReader())
1394 {
1395 using (var cmd = new Command())
1396 {
1397 cmd.Add(ConstValues.REDIS_COMMAND_ZREVRANK);
1398 cmd.Add(key);
1399 cmd.Add(member);
1400 using (var result = TcpClient.Send(cmd, c.Client))
1401 {
1402 if (result.ResultData != null)
1403 {
1404 return int.Parse(result.ResultData.ToString());
1405 }
1406 }
1407 }
1408 }
1409 return 0;
1410 }
1411
1412 /// <summary>
1413 /// 移除有序集key中的一个或多个成员,不存在的成员将被忽略。
1414 /// </summary>
1415 /// <param name="key"></param>
1416 /// <param name="member"></param>
1417 public void Zrem(string key, int member)
1418 {
1419 using (var c = GetWriter())
1420 {
1421 using (var cmd = new Command())
1422 {
1423 cmd.Add(ConstValues.REDIS_COMMAND_ZREM);
1424 cmd.Add(key);
1425 cmd.Add(member.ToString());
1426 using (TcpClient.Send(cmd, c.Client))
1427 {
1428 }
1429 }
1430 }
1431 }
1432
1433 /// <summary>
1434 /// 返回有序集key中,成员member的score值。
1435 /// </summary>
1436 /// <param name="key"></param>
1437 /// <param name="member"></param>
1438 /// <returns></returns>
1439 public int Zscore(string key, string member)
1440 {
1441 using (var c = GetReader())
1442 {
1443 using (var cmd = new Command())
1444 {
1445 cmd.Add(ConstValues.REDIS_COMMAND_ZSCORE);
1446 cmd.Add(key);
1447 cmd.Add(member);
1448 using (var result = TcpClient.Send(cmd, c.Client))
1449 {
1450 if (result.ResultDataBlock.Count > 0)
1451 {
1452 var value = "";
1453 value = (string)FromRedis(result.ResultDataBlock[0], DataType.String, Type.GetType(value));
1454 return int.Parse(value);
1455 }
1456 }
1457 }
1458 }
1459 return 0;
1460 }
1461
1462 /// <summary>
1463 /// 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略。
1464 /// </summary>
1465 /// <typeparam name="T"></typeparam>
1466 /// <param name="key"></param>
1467 /// <param name="members"></param>
1468 /// <param name="type"></param>
1469 /// <returns></returns>
1470 public int Sadd<T>(string key, List<T> members, DataType type)
1471 {
1472 using (var c = GetWriter())
1473 {
1474 using (var cmd = new Command())
1475 {
1476 cmd.Add(ConstValues.REDIS_COMMAND_SADD);
1477 cmd.Add(key);
1478 foreach (var member in members)
1479 ToRedis(member, type, cmd);
1480 using (var result = TcpClient.Send(cmd, c.Client))
1481 {
1482 if (result.ResultData != null)
1483 {
1484 return int.Parse(result.ResultData.ToString());
1485 }
1486 }
1487 }
1488 }
1489 return 0;
1490 }
1491
1492 /// <summary>
1493 /// 将member元素加入到集合key当中,已经存在于集合的member元素将被忽略。
1494 /// </summary>
1495 /// <typeparam name="T"></typeparam>
1496 /// <param name="key"></param>
1497 /// <param name="member"></param>
1498 /// <param name="type"></param>
1499 /// <returns></returns>
1500 public int Sadd<T>(string key, T member, DataType type)
1501 {
1502 using (var c = GetWriter())
1503 {
1504 using (var cmd = new Command())
1505 {
1506 cmd.Add(ConstValues.REDIS_COMMAND_SADD);
1507 cmd.Add(key);
1508 ToRedis(member, type, cmd);
1509 using (var result = TcpClient.Send(cmd, c.Client))
1510 {
1511 if (result.ResultData != null)
1512 {
1513 return int.Parse(result.ResultData.ToString());
1514 }
1515 }
1516 }
1517 }
1518 return 0;
1519 }
1520
1521 /// <summary>
1522 /// 返回集合key的基数(集合中元素的数量)。
1523 /// </summary>
1524 /// <param name="key"></param>
1525 /// <returns></returns>
1526 public int Scard(string key)
1527 {
1528 using (var c = GetReader())
1529 {
1530 using (var cmd = new Command())
1531 {
1532 cmd.Add(ConstValues.REDIS_COMMAND_SCARD);
1533 cmd.Add(key);
1534 using (var result = TcpClient.Send(cmd, c.Client))
1535 {
1536 if (result.ResultData != null)
1537 {
1538 return int.Parse(result.ResultData.ToString());
1539 }
1540 }
1541 }
1542 }
1543 return 0;
1544 }
1545
1546 /// <summary>
1547 /// 判断member元素是否是集合key的成员。
1548 /// </summary>
1549 /// <typeparam name="T"></typeparam>
1550 /// <param name="key"></param>
1551 /// <param name="member"></param>
1552 /// <param name="type"></param>
1553 /// <returns></returns>
1554 public bool Sismember<T>(string key, T member, DataType type)
1555 {
1556 var r = 0;
1557 using (var c = GetReader())
1558 {
1559 using (var cmd = new Command())
1560 {
1561 cmd.Add(ConstValues.REDIS_COMMAND_SISMEMBER);
1562 cmd.Add(key);
1563 ToRedis(member, type, cmd);
1564 using (var result = TcpClient.Send(cmd, c.Client))
1565 {
1566 if (result.ResultData != null)
1567 {
1568 r = int.Parse(result.ResultData.ToString());
1569 }
1570 }
1571 }
1572 }
1573 return r > 0;
1574 }
1575
1576 /// <summary>
1577 /// 返回集合key中的所有成员。
1578 /// </summary>
1579 /// <typeparam name="T"></typeparam>
1580 /// <param name="key"></param>
1581 /// <param name="type"></param>
1582 /// <returns></returns>
1583 public List<T> Smember<T>(string key, DataType type)
1584 {
1585 List<T> sets = null;
1586 using (var c = GetReader())
1587 {
1588 using (var cmd = new Command())
1589 {
1590 cmd.Add(ConstValues.REDIS_COMMAND_SMEMBERS);
1591 cmd.Add(key);
1592 using (var result = TcpClient.Send(cmd, c.Client))
1593 {
1594 if (result.ResultDataBlock.Count > 0)
1595 {
1596 sets = new List<T>();
1597 foreach (var currentdata in result.ResultDataBlock)
1598 {
1599 sets.Add((T)FromRedis(currentdata, type, typeof(T)));
1600 }
1601 }
1602 }
1603 }
1604 }
1605 return sets;
1606 }
1607
1608 /// <summary>
1609 /// 移除集合key中的一个或多个member元素,不存在的member元素会被忽略。
1610 /// </summary>
1611 /// <typeparam name="T"></typeparam>
1612 /// <param name="key"></param>
1613 /// <param name="member"></param>
1614 /// <param name="type"></param>
1615 /// <returns></returns>
1616 public int Srem<T>(string key, T member, DataType type)
1617 {
1618 using (var c = GetWriter())
1619 {
1620 using (var cmd = new Command())
1621 {
1622 cmd.Add(ConstValues.REDIS_COMMAND_SREM);
1623 cmd.Add(key);
1624 ToRedis(member, type, cmd);
1625 using (var result = TcpClient.Send(cmd, c.Client))
1626 {
1627 if (result.ResultData != null)
1628 {
1629 return int.Parse(result.ResultData.ToString());
1630 }
1631 }
1632 }
1633 }
1634 return 0;
1635 }
1636
1637 /// <summary>
1638 /// 返回或保存给定列表、集合、有序集合key中经过排序的元素。
1639 /// </summary>
1640 /// <param name="key"></param>
1641 /// <param name="offset"></param>
1642 /// <param name="count"></param>
1643 /// <param name="bYpattern"></param>
1644 /// <param name="geTpattern"></param>
1645 /// <param name="alpha"></param>
1646 /// <param name="storeDestination"></param>
1647 /// <param name="orderby"></param>
1648 /// <param name="type"></param>
1649 /// <param name="dtype"></param>
1650 /// <returns></returns>
1651 public IList<object> Sort(string key, int? offset, int? count, string bYpattern, string geTpattern, bool alpha,
1652 string storeDestination,
1653 SortOrderType orderby, Type type, DataType dtype)
1654 {
1655 var result = new List<object>();
1656 using (var c = GetReader())
1657 {
1658 using (var cmd = new Command())
1659 {
1660 cmd.Add(ConstValues.REDIS_COMMAND_SORT);
1661 cmd.Add(key);
1662 if (!string.IsNullOrEmpty(bYpattern))
1663 {
1664 cmd.Add("BY");
1665 cmd.Add(bYpattern);
1666 }
1667 if (!string.IsNullOrEmpty(geTpattern))
1668 {
1669 cmd.Add("GET");
1670 cmd.Add(geTpattern);
1671 }
1672 if (offset != null)
1673 {
1674 cmd.Add("LIMIT");
1675 cmd.Add(offset.Value.ToString());
1676 cmd.Add(count == null ? "1000" : count.Value.ToString());
1677 }
1678 if (alpha)
1679 {
1680 cmd.Add("alpha");
1681 }
1682 cmd.Add(Enum.GetName(typeof(SortOrderType), orderby));
1683 if (!string.IsNullOrEmpty(storeDestination))
1684 {
1685 cmd.Add("STORE");
1686 cmd.Add(storeDestination);
1687 }
1688 using (var rd = TcpClient.Send(cmd, c.Client))
1689 {
1690 foreach (var item in rd.ResultDataBlock)
1691 {
1692 result.Add(FromRedis(item, dtype, type));
1693 }
1694 }
1695 }
1696 }
1697 return result;
1698 }
1699
1700 private void ToRedis(object value, DataType type, Command cmd)
1701 {
1702 if (type == DataType.String)
1703 {
1704 cmd.Add((string)value);
1705 }
1706 else
1707 {
1708 cmd.AddProtobuf(value);
1709 }
1710 }
1711
1712 private object FromRedis(ArraySegment<byte> data, DataType type, Type otype)
1713 {
1714 if (type == DataType.String)
1715 {
1716 return data.GetString();
1717 }
1718 else
1719 {
1720 try
1721 {
1722 return data.GetProtobuf(otype);
1723 }
1724 catch (Exception exception)
1725 {
1726 Log.Instance.Error($"{otype} type get error!", exception);
1727 return null;
1728 }
1729 }
1730 }
1731
1732 #region 订阅与发布
1733
1734 /// <summary>
1735 /// 发布消息到指定频道
1736 /// </summary>
1737 /// <param name="channel">频道</param>
1738 /// <param name="message">消息</param>
1739 /// <returns></returns>
1740 public object Publish(string channel, string message)
1741 {
1742 try
1743 {
1744 using (var c = GetWriter())
1745 {
1746 using (var cmd = new Command())
1747 {
1748 cmd.Add(ConstValues.REDIS_COMMAND_PUBLISH);
1749 cmd.Add(channel);
1750 cmd.Add(message);
1751 using (var result = TcpClient.Send(cmd, c.Client))
1752 {
1753 if (result.ResultData != null)
1754 {
1755 return result.ResultData.ToString();
1756 }
1757 }
1758 }
1759 }
1760 return null;
1761 }
1762 catch (Exception ex)
1763 {
1764 throw new Exception("Publish:{0}", ex);
1765 }
1766 }
1767
1768 public void Subscribe(string channelName)
1769 {
1770 try
1771 {
1772 using (var c = GetWriter())
1773 {
1774 using (var cmd = new Command())
1775 {
1776 cmd.Add(ConstValues.REDIS_COMMAND_SUBSCRIBE);
1777 cmd.Add(channelName);
1778 using (TcpClient.Send(cmd, c.Client))
1779 {
1780 }
1781 }
1782 }
1783 }
1784 catch (Exception ex)
1785 {
1786 throw new Exception("Subscribe:{0}", ex);
1787 }
1788 }
1789
1790 public void PSubscribe(string channelName)
1791 {
1792 Init(channelName);
1793 IsPattern = true;
1794 var thread = new Thread(() => CheckSubscribe(IsPattern));
1795 thread.Start();
1796 }
1797
1798 public void UnSubscribe(string channelName)
1799 {
1800 UnSubscribe();
1801 }
1802
1803 public void UnPSubscribe(string channelName)
1804 {
1805 UnSubscribe();
1806 }
1807
1808 private void Init(string channelName)
1809 {
1810 ChannelName = channelName;
1811 }
1812
1813 private void Run(bool isPattern = false)
1814 {
1815 Result repy;
1816 if (isPattern)
1817 {
1818 using (var c = GetWriter())
1819 {
1820 using (var cmd = new Command())
1821 {
1822 cmd.Add(ConstValues.REDIS_COMMAND_PSUBSCRIBE);
1823 cmd.Add(ChannelName);
1824 repy = TcpClient.Send(cmd, c.Client);
1825 while (true)
1826 {
1827 if (repy.ResultData is object[])
1828 {
1829 var val = repy.ResultData as object[];
1830 if (val[0].ToString().ToLower().Contains("unsubscribe"))
1831 {
1832 if (OnUnSubscribe != null)
1833 OnUnSubscribe(val);
1834 break;
1835 }
1836 }
1837 if (OnMessage != null)
1838 OnMessage(this, repy);
1839 }
1840 }
1841 }
1842 }
1843 else
1844 {
1845 using (var c = GetWriter())
1846 {
1847 using (var cmd = new Command())
1848 {
1849 cmd.Add(ConstValues.REDIS_COMMAND_SUBSCRIBE);
1850 cmd.Add(ChannelName);
1851 repy = TcpClient.Send(cmd, c.Client);
1852 while (true)
1853 {
1854 if (repy.ResultData is object[])
1855 {
1856 var val = repy.ResultData as object[];
1857 if (val[0].ToString().ToLower().Contains("unsubscribe"))
1858 {
1859 OnUnSubscribe?.Invoke(val);
1860 break;
1861 }
1862 }
1863 OnMessage?.Invoke(this, repy);
1864 }
1865 }
1866 }
1867 }
1868
1869 OnSuccess?.Invoke((object[])repy.ResultData);
1870 }
1871
1872 private void CheckSubscribe(bool isPattern = false)
1873 {
1874 try
1875 {
1876 Run(isPattern);
1877 }
1878 catch (ThreadAbortException)
1879 {
1880 }
1881 catch (Exception exception)
1882 {
1883 if (OnError != null)
1884 OnError(exception);
1885 }
1886 }
1887
1888 private void UnSubscribe()
1889 {
1890 try
1891 {
1892 if (IsPattern)
1893 {
1894 using (var c = GetWriter())
1895 {
1896 using (var cmd = new Command())
1897 {
1898 cmd.Add(ConstValues.REDIS_COMMAND_PUNSUBSCRIBE);
1899 cmd.Add(ChannelName);
1900 TcpClient.Send(cmd, c.Client);
1901 }
1902 }
1903 }
1904 else
1905 {
1906 using (var c = GetWriter())
1907 {
1908 using (var cmd = new Command())
1909 {
1910 cmd.Add(ConstValues.REDIS_COMMAND_UNSUBSCRIBE);
1911 cmd.Add(ChannelName);
1912 TcpClient.Send(cmd, c.Client);
1913 }
1914 }
1915 }
1916 }
1917 catch (Exception exception)
1918 {
1919 Debug.Print("Hredis UnSubscribe:" + exception.Message);
1920 }
1921 }
1922
1923 #endregion
1924
1925 #region 属性
1926
1927 private int _readHostIndex;
1928
1929 private int _writeHostIndex;
1930
1931 /// <summary>
1932 /// Redis 读取服务器组
1933 /// </summary>
1934 public IList<RedisHost> ReadHosts { get; } = new List<RedisHost>();
1935
1936 /// <summary>
1937 /// Redis 写入服务器组
1938 /// </summary>
1939 public IList<RedisHost> WriteHosts { get; } = new List<RedisHost>();
1940
1941 /// <summary>
1942 /// 默认客户端
1943 /// </summary>
1944 public static RedisClient DefaultDB { get; }
1945
1946 public int DB { get; set; }
1947
1948 #endregion
1949
1950 #region 取得服务器
1951
1952 /// <summary>
1953 /// 取得写入服务器
1954 /// </summary>
1955 /// <returns></returns>
1956 public RedisHost.ClientItem GetWriter()
1957 {
1958 RedisHost host;
1959 RedisHost.ClientItem client;
1960 for (var i = 0; i < WriteHosts.Count; i++)
1961 {
1962 host = WriteHosts[_writeHostIndex % WriteHosts.Count];
1963 if (host.Available)
1964 {
1965 client = host.Pop();
1966 SelectDB(client.Client);
1967 return client;
1968 }
1969 else
1970 {
1971 host.Detect();
1972 }
1973 _writeHostIndex++;
1974 }
1975
1976 throw new Exception("write host not Available!");
1977 }
1978
1979 /// <summary>
1980 /// 取得读取服务器
1981 /// </summary>
1982 /// <returns></returns>
1983 public RedisHost.ClientItem GetReader()
1984 {
1985 for (var i = 0; i < ReadHosts.Count; i++)
1986 {
1987 var host = ReadHosts[_readHostIndex % ReadHosts.Count];
1988 if (host.Available)
1989 {
1990 var client = host.Pop();
1991 SelectDB(client.Client);
1992 return client;
1993 }
1994 else
1995 {
1996 host.Detect();
1997 }
1998 _readHostIndex++;
1999 }
2000 throw new Exception("read host not Available!");
2001 }
2002
2003 #endregion
2004
2005 #region 默认构造
2006
2007 /// <summary>
2008 /// 默认构造
2009 /// </summary>
2010 public RedisClient()
2011 {
2012 Init();
2013 }
2014
2015 /// <summary>
2016 /// 初始化
2017 /// </summary>
2018 private void Init()
2019 {
2020 if (RedisClientSeting.Current.SingleMode)
2021 {
2022 foreach (var hostStrings in RedisClientSeting.Current.RedisServer)
2023 {
2024 WriteHosts.Add(new RedisHost(hostStrings.Host, hostStrings.Connections));
2025 ReadHosts.Add(new RedisHost(hostStrings.Host, hostStrings.Connections));
2026 }
2027 }
2028 else
2029 {
2030 foreach (var hostStrings in RedisClientSeting.Current.Writes)
2031 {
2032 WriteHosts.Add(new RedisHost(hostStrings.Host, hostStrings.Connections));
2033 }
2034 foreach (var hostStrings in RedisClientSeting.Current.Reads)
2035 {
2036 ReadHosts.Add(new RedisHost(hostStrings.Host, hostStrings.Connections));
2037 }
2038 }
2039
2040 DB = RedisClientSeting.Current.DbIndex;
2041 }
2042
2043 /// <summary>
2044 /// 静态构造
2045 /// </summary>
2046 static RedisClient()
2047 {
2048 DefaultDB = new RedisClient();
2049 }
2050
2051 /// <summary>
2052 /// 静态构造
2053 /// </summary>
2054 /// <param name="db">客户端</param>
2055 /// <returns></returns>
2056 public static RedisClient GetClient(RedisClient db)
2057 {
2058 return db ?? DefaultDB;
2059 }
2060
2061 #endregion
2062
2063 #region Delete
2064
2065 /// <summary>
2066 /// </summary>
2067 /// <param name="keys"></param>
2068 /// <returns></returns>
2069 public int Delete(params string[] keys)
2070 {
2071 using (var c = GetWriter())
2072 {
2073 using (var cmd = new Command())
2074 {
2075 cmd.Add(ConstValues.REDIS_COMMAND_DEL);
2076 foreach (var key in keys)
2077 {
2078 cmd.Add(key);
2079 }
2080 using (var result = TcpClient.Send(cmd, c.Client))
2081 {
2082 return int.Parse(result.ResultData.ToString());
2083 }
2084 }
2085 }
2086 }
2087
2088 /// <summary>
2089 /// 删除哈希表key中的一个或多个指定域,不存在的域将被忽略。
2090 /// </summary>
2091 /// <param name="key"></param>
2092 /// <param name="field"></param>
2093 /// <returns>被成功移除的域的数量,不包括被忽略的域。</returns>
2094 public int HDelete(string key, string field)
2095 {
2096 using (var c = GetWriter())
2097 {
2098 using (var cmd = new Command())
2099 {
2100 cmd.Add(ConstValues.REDIS_COMMAND_HDEL);
2101 cmd.Add(key);
2102 cmd.Add(field);
2103 using (var result = TcpClient.Send(cmd, c.Client))
2104 {
2105 return int.Parse(result.ResultData.ToString());
2106 }
2107 }
2108 }
2109 }
2110
2111 #endregion
2112
2113
2114 public string Info(string para, DataType dtype)
2115 {
2116 using (var c = GetReader())
2117 {
2118 using (var cmd = new Command())
2119 {
2120 cmd.Add(ConstValues.REDIS_COMMAND_INFO);
2121 cmd.Add(para);
2122 using (var result = TcpClient.Send(cmd, c.Client))
2123 {
2124 if (result.ResultDataBlock.Count > 0)
2125 {
2126 return FromRedis(result.ResultDataBlock[0], dtype, null).ToString();
2127 }
2128 }
2129 }
2130 }
2131 return string.Empty;
2132 }
2133 }
View Code

里面涉及到复杂对象的ProtoBuff序列化和内存溢出处理等细节不便多说,需要交流讨论的可以联系我。