码迷,mamicode.com
首页 > Web开发 > 详细

Redis .Net客户端源码

时间:2017-02-08 11:47:15      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:getc   nts   reads   存储   cte   this   内存分配   sdn   释放   

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客户端部分源码

技术分享
   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序列化和内存溢出处理等细节不便多说,需要交流讨论的可以联系我。

Redis .Net客户端源码

标签:getc   nts   reads   存储   cte   this   内存分配   sdn   释放   

原文地址:http://www.cnblogs.com/lianming37/p/6377350.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!