zoukankan      html  css  js  c++  java
  • Redis .Net客户端源码

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

  • 相关阅读:
    一些tips
    微信小程序之后端处理
    微信小程序之前端代码篇
    微信小程序踩坑之前端问题处理篇
    Vue组件封装之一键复制文本到剪贴板
    读别人的代码之bug的发现
    解析webpack插件html-webpack-plugin
    数组去重方法整理
    如何理解EventLoop--浏览器篇
    axios和vue-axios的关系
  • 原文地址:https://www.cnblogs.com/gbat/p/6377350.html
Copyright © 2011-2022 走看看