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客户端部分源码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
里面涉及到复杂对象的ProtoBuff序列化和内存溢出处理等细节不便多说,需要交流讨论的可以联系我。