usingHslCommunication.Core;usingHslCommunication.Core.IMessage;usingHslCommunication.Core.Net;usingSystem;usingSystem.Collections.Generic;usingSystem.Net.Sockets;usingSystem.Text;namespaceHslCommunication.Enthernet.Redis{///<summary>///这是一个redis的客户端类,支持读取,写入,发布订阅,但是不支持订阅,如果需要订阅,请使用另一个类///</summary>publicclassRedisClient:NetworkDoubleBase<HslMessage,RegularByteTransform>{#regionConstructor///<summary>///实例化一个客户端的对象,用于和服务器通信///</summary>///<paramname="ipAddress">服务器的ip地址</param>///<paramname="port">服务器的端口号</param>///<paramname="password">密码,如果服务器没有设置,密码设置为null</param>publicRedisClient(stringipAddress,intport,stringpassword){IpAddress=ipAddress;Port=port;ReceiveTimeOut=30000;this.password=password;}///<summary>///实例化一个客户端对象,需要手动指定Ip地址和端口///</summary>///<paramname="password">密码,如果服务器没有设置,密码设置为null</param>publicRedisClient(stringpassword){ReceiveTimeOut=30000;this.password=password;}#endregion#regionOverride///<summary>///如果设置了密码,对密码进行验证///</summary>///<paramname="socket">网络的套接字服务</param>///<returns>是否成功的对象</returns>protectedoverrideOperateResultInitializationOnConnect(Socketsocket){if(!string.IsNullOrEmpty(this.password)){byte[]command=RedisHelper.PackStringCommand(newstring[]{"AUTH",this.password});OperateResult<byte[]>read=ReadFromCoreServer(socket,command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<string>(read);stringmsg=Encoding.UTF8.GetString(read.Content);if(!msg.StartsWith("+"))returnnewOperateResult<string>(msg);returnOperateResult.CreateSuccessResult(msg.Substring(1).TrimEnd('\r','\n'));}returnbase.InitializationOnConnect(socket);}///<summary>///在其他指定的套接字上,使用报文来通讯,传入需要发送的消息,返回一条完整的数据指令///</summary>///<paramname="socket">指定的套接字</param>///<paramname="send">发送的完整的报文信息</param>///<remarks>///无锁的基于套接字直接进行叠加协议的操作。///</remarks>///<example>///假设你有一个自己的socket连接了设备,本组件可以直接基于该socket实现modbus读取,三菱读取,西门子读取等等操作,前提是该服务器支持多协议,虽然这个需求听上去比较变态,但本组件支持这样的操作。///<codelang="cs"source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDoubleBase.cs"region="ReadFromCoreServerExample1"title="ReadFromCoreServer示例"/>///</example>///<returns>接收的完整的报文信息</returns>publicoverrideOperateResult<byte[]>ReadFromCoreServer(Socketsocket,byte[]send){OperateResultsendResult=Send(socket,send);if(!sendResult.IsSuccess)returnOperateResult.CreateFailedResult<byte[]>(sendResult);stringtmp=BasicFramework.SoftBasic.ByteToHexString(send,' ');//接收超时时间大于0时才允许接收远程的数据if(ReceiveTimeOut<0)returnOperateResult.CreateSuccessResult(newbyte[0]);//接收数据信息returnRedisHelper.ReceiveCommand(socket);}#endregion#regionCustomer///<summary>///自定义的指令交互方法,该指令用空格分割,举例:LTRIMAAAAA0999就是收缩列表,GETAAA就是获取键值,需要对返回的数据进行二次分析///</summary>///<paramname="command">举例:LTRIMAAAAA0999就是收缩列表,GETAAA就是获取键值</param>///<returns>从服务器返回的结果数据对象</returns>publicOperateResult<string>ReadCustomer(stringcommand){byte[]byteCommand=RedisHelper.PackStringCommand(command.Split(' '));OperateResult<byte[]>read=ReadFromCoreServer(byteCommand);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<string>(read);returnOperateResult.CreateSuccessResult(Encoding.UTF8.GetString(read.Content));}#endregion#regionBaseOperate///<summary>///向服务器请求指定,并返回数字的结果对象///</summary>///<paramname="commands">命令数组</param>///<returns>数字的结果对象</returns>publicOperateResult<int>OperateNumberFromServer(string[]commands){byte[]command=RedisHelper.PackStringCommand(commands);OperateResult<byte[]>read=ReadFromCoreServer(command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<int>(read);stringmsg=Encoding.UTF8.GetString(read.Content);if(!msg.StartsWith(":"))returnnewOperateResult<int>(msg);returnRedisHelper.GetNumberFromCommandLine(read.Content);}///<summary>///向服务器请求指令,并返回long数字的结果对象///</summary>///<paramname="commands">命令数组</param>///<returns>long数字的结果对象</returns>publicOperateResult<long>OperateLongNumberFromServer(string[]commands){byte[]command=RedisHelper.PackStringCommand(commands);OperateResult<byte[]>read=ReadFromCoreServer(command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<long>(read);stringmsg=Encoding.UTF8.GetString(read.Content);if(!msg.StartsWith(":"))returnnewOperateResult<long>(msg);returnRedisHelper.GetLongNumberFromCommandLine(read.Content);}///<summary>///向服务器请求指令,并返回字符串的结果对象///</summary>///<paramname="commands">命令数组</param>///<returns>字符串的结果对象</returns>publicOperateResult<string>OperateStringFromServer(string[]commands){byte[]command=RedisHelper.PackStringCommand(commands);OperateResult<byte[]>read=ReadFromCoreServer(command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<string>(read);returnRedisHelper.GetStringFromCommandLine(read.Content);}///<summary>///向服务器请求指令,并返回字符串数组的结果对象///</summary>///<paramname="commands">命令数组</param>///<returns>字符串数组的结果对象</returns>publicOperateResult<string[]>OperateStringsFromServer(string[]commands){byte[]command=RedisHelper.PackStringCommand(commands);OperateResult<byte[]>read=ReadFromCoreServer(command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<string[]>(read);returnRedisHelper.GetStringsFromCommandLine(read.Content);}///<summary>///向服务器请求指令,并返回状态的结果对象,通常用于写入的判断,或是请求类型的判断///</summary>///<paramname="commands">命令数组</param>///<returns>是否成功的结果对象</returns>publicOperateResult<string>OperateStatusFromServer(string[]commands){byte[]command=RedisHelper.PackStringCommand(commands);OperateResult<byte[]>read=ReadFromCoreServer(command);if(!read.IsSuccess)returnOperateResult.CreateFailedResult<string>(read);stringmsg=Encoding.UTF8.GetString(read.Content);if(!msg.StartsWith("+"))returnnewOperateResult<string>(msg);returnOperateResult.CreateSuccessResult(msg.Substring(1).TrimEnd('\r','\n'));}#endregion#regionKeyOperate///<summary>///删除给定的一个或多个key。不存在的key会被忽略。///</summary>///<paramname="keys">关键字</param>///<returns>被删除key的数量。</returns>publicOperateResult<int>DeleteKey(string[]keys){List<string>list=newList<string>();list.Add("DEL");list.AddRange(keys);returnOperateNumberFromServer(list.ToArray());}///<summary>///删除给定的一个或多个key。不存在的key会被忽略。///</summary>///<paramname="key">关键字</param>///<returns>被删除key的数量。</returns>publicOperateResult<int>DeleteKey(stringkey){returnDeleteKey(newstring[]{key});}///<summary>///检查给定key是否存在。若key存在,返回1,否则返回0。///</summary>///<paramname="key">关键字</param>///<returns>若key存在,返回1,否则返回0。</returns>publicOperateResult<int>ExistsKey(stringkey){returnOperateNumberFromServer(newstring[]{"EXISTS",key});}///<summary>///为给定key设置生存时间,当key过期时(生存时间为0),它会被自动删除。设置成功返回1。当key不存在或者不能为key设置生存时间时,返回0。///</summary>///<paramname="key">关键字</param>///<returns>///设置成功返回1。当key不存在或者不能为key设置生存时间时,返回0。///</returns>publicOperateResult<int>ExpireKey(stringkey){returnOperateNumberFromServer(newstring[]{"EXPIRE",key});}///<summary>///查找所有符合给定模式pattern的key。///*匹配数据库中所有key。///h?llo匹配hello,hallo和hxllo等。///h[ae]llo匹配hello和hallo,但不匹配hillo。///</summary>///<paramname="pattern">给定模式</param>///<returns>符合给定模式的key列表。</returns>publicOperateResult<string[]>ReadAllKeys(stringpattern){returnOperateStringsFromServer(newstring[]{"KEYS",pattern});}///<summary>///将当前数据库的key移动到给定的数据库db当中。///如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key,或者key不存在于当前数据库,那么MOVE没有任何效果。///因此,也可以利用这一特性,将MOVE当作锁(locking)原语(primitive)。///</summary>///<paramname="key">关键字</param>///<paramname="db">数据块</param>///<returns>是否移动成功</returns>publicOperateResultMoveKey(stringkey,intdb){returnOperateStatusFromServer(newstring[]{"MOVE",key,db.ToString()});}///<summary>///移除给定key的生存时间,将这个key从『易失的』(带生存时间key)转换成『持久的』(一个不带生存时间、永不过期的key)。///当生存时间移除成功时,返回1.///如果key不存在或key没有设置生存时间,返回0。///</summary>///<paramname="key">关键字</param>///<returns>///当生存时间移除成功时,返回1.///如果key不存在或key没有设置生存时间,返回0。///</returns>publicOperateResult<int>PersistKey(stringkey){returnOperateNumberFromServer(newstring[]{"PERSIST",key});}///<summary>///从当前数据库中随机返回(不删除)一个key。///当数据库不为空时,返回一个key。///当数据库为空时,返回nil。///</summary>///<returns>///当数据库不为空时,返回一个key。///当数据库为空时,返回nil。///</returns>publicOperateResult<string>ReadRandomKey(){returnOperateStringFromServer(newstring[]{"RANDOMKEY"});}///<summary>///将key改名为newkey。///当key和newkey相同,或者key不存在时,返回一个错误。///当newkey已经存在时,RENAME命令将覆盖旧值。///</summary>///<paramname="key1">旧的key</param>///<paramname="key2">新的key</param>///<returns>///改名成功时提示OK,失败时候返回一个错误。///</returns>publicOperateResultRenameKey(stringkey1,stringkey2){returnOperateStatusFromServer(newstring[]{"RENAME",key1,key2});}///<summary>///返回key所储存的值的类型。none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)///</summary>///<paramname="key">关键字</param>///<returns>类型</returns>publicOperateResult<string>ReadKeyType(stringkey){returnOperateStatusFromServer(newstring[]{"TYPE",key});}#endregion#regionStringOperate///<summary>///如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值的末尾。///如果key不存在,APPEND就简单地将给定key设为value,就像执行SETkeyvalue一样。///返回追加value之后,key中字符串的长度。///</summary>///<paramname="key">关键字</param>///<paramname="value">数值</param>///<returns>///追加value之后,key中字符串的长度。///</returns>publicOperateResult<int>AppendKey(stringkey,stringvalue){returnOperateNumberFromServer(newstring[]{"APPEND",key,value});}///<summary>///将key中储存的数字值减一。如果key不存在,那么key的值会先被初始化为0,然后再执行DECR操作。///如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。///本操作的值限制在64位(bit)有符号数字表示之内。///返回执行DECR命令之后key的值。///</summary>///<paramname="key">关键字</param>///<returns>执行DECR命令之后key的值。</returns>publicOperateResult<long>DecrementKey(stringkey){returnOperateLongNumberFromServer(newstring[]{"DECR",key});}///<summary>///将key所储存的值减去减量decrement。如果key不存在,那么key的值会先被初始化为0,然后再执行DECR操作。///如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。///本操作的值限制在64位(bit)有符号数字表示之内。///返回减去decrement之后,key的值。///</summary>///<paramname="key">关键字</param>///<paramname="value">操作的值</param>///<returns>返回减去decrement之后,key的值。</returns>publicOperateResult<long>DecrementKey(stringkey,longvalue){returnOperateLongNumberFromServer(newstring[]{"DECRBY",key,value.ToString()});}///<summary>///返回key所关联的字符串值。如果key不存在那么返回特殊值nil。///假如key储存的值不是字符串类型,返回一个错误,因为GET只能用于处理字符串值。///</summary>///<paramname="key">关键字</param>///<returns>当key不存在时,返回nil,否则,返回key的值。</returns>publicOperateResult<string>ReadKey(stringkey){returnOperateStringFromServer(newstring[]{"GET",key});}///<summary>///返回key中字符串值的子字符串,字符串的截取范围由start和end两个偏移量决定(包括start和end在内)。///负数偏移量表示从字符串最后开始计数,-1表示最后一个字符,-2表示倒数第二个,以此类推。///返回截取得出的子字符串。///</summary>///<paramname="key">关键字</param>///<paramname="start">截取开始的位置</param>///<paramname="end">截取结束的位置</param>///<returns>返回截取得出的子字符串。</returns>publicOperateResult<string>ReadKeyRange(stringkey,intstart,intend){returnOperateStringFromServer(newstring[]{"GETRANGE",key,start.ToString(),end.ToString()});}///<summary>///将给定key的值设为value,并返回key的旧值(oldvalue)。当key存在但不是字符串类型时,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="value">新的值</param>///<returns>返回给定key的旧值。当key没有旧值时,也即是,key不存在时,返回nil。</returns>publicOperateResult<string>ReadAndWriteKey(stringkey,stringvalue){returnOperateStringFromServer(newstring[]{"GETSET",key,value});}///<summary>///将key中储存的数字值增一。如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。///如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。///返回执行INCR命令之后key的值。///</summary>///<paramname="key">关键字</param>///<returns>返回执行INCR命令之后key的值。</returns>publicOperateResult<long>IncrementKey(stringkey){returnOperateLongNumberFromServer(newstring[]{"INCR",key});}///<summary>///将key所储存的值加上增量increment。如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。///如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="value">增量数据</param>///<returns>加上increment之后,key的值。</returns>publicOperateResult<long>IncrementKey(stringkey,longvalue){returnOperateLongNumberFromServer(newstring[]{"INCRBY",key,value.ToString()});}///<summary>///将key所储存的值加上增量increment。如果key不存在,那么key的值会先被初始化为0,然后再执行INCRBYFLOAT操作。///如果命令执行成功,那么key的值会被更新为(执行加法之后的)新值,并且新值会以字符串的形式返回给调用者///</summary>///<paramname="key">关键字</param>///<paramname="value">增量数据</param>///<returns>执行命令之后key的值。</returns>publicOperateResult<string>IncrementKey(stringkey,floatvalue){returnOperateStringFromServer(newstring[]{"INCRBYFLOAT",key,value.ToString()});}///<summary>///返回所有(一个或多个)给定key的值。///如果给定的key里面,有某个key不存在,那么这个key返回特殊值null。因此,该命令永不失败。///</summary>///<paramname="keys">关键字数组</param>///<returns>一个包含所有给定key的值的列表。</returns>publicOperateResult<string[]>ReadKey(string[]keys){List<string>list=newList<string>();list.Add("MGET");list.AddRange(keys);returnOperateStringsFromServer(list.ToArray());}///<summary>///同时设置一个或多个key-value对。///如果某个给定key已经存在,那么MSET会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用MSETNX命令:它只会在所有给定key都不存在的情况下进行设置操作。///</summary>///<paramname="keys">关键字数组</param>///<paramname="values">值数组</param>///<returns>总是返回OK(因为MSET不可能失败)</returns>publicOperateResultWriteKey(string[]keys,string[]values){if(keys==null)thrownewArgumentNullException("keys");if(values==null)thrownewArgumentNullException("values");if(keys.Length!=values.Length)thrownewArgumentException("Two arguement not same length");List<string>list=newList<string>();list.Add("MSET");for(inti=0;i<keys.Length;i++){list.Add(keys[i]);list.Add(values[i]);}returnOperateStatusFromServer(list.ToArray());}///<summary>///将字符串值value关联到key。///如果key已经持有其他值,SET就覆写旧值,无视类型。///对于某个原本带有生存时间(TTL)的键来说,当SET命令成功在这个键上执行时,这个键原有的TTL将被清除。///</summary>///<paramname="key">关键字</param>///<paramname="value">数据值</param>///<returns>SET在设置操作成功完成时,才返回OK。</returns>publicOperateResultWriteKey(stringkey,stringvalue){returnOperateStatusFromServer(newstring[]{"SET",key,value});}///<summary>///将字符串值value关联到key。并发布一个订阅的频道数据,都成功时,才返回成功///</summary>///<paramname="key">关键字</param>///<paramname="value">数据值</param>///<returns>是否成功的结果对象</returns>publicOperateResultWriteAndPublishKey(stringkey,stringvalue){OperateResultwrite=WriteKey(key,value);if(!write.IsSuccess)returnwrite;returnPublish(key,value);}///<summary>///将值value关联到key,并将key的生存时间设为seconds(以秒为单位)。如果key已经存在,SETEX命令将覆写旧值。///</summary>///<paramname="key">关键字</param>///<paramname="value">数值</param>///<paramname="seconds">生存时间,单位秒</param>///<returns>设置成功时返回OK。当seconds参数不合法时,返回一个错误。</returns>publicOperateResultWriteExpireKey(stringkey,stringvalue,longseconds){returnOperateStatusFromServer(newstring[]{"SETEX",key,seconds.ToString(),value});}///<summary>///将key的值设为value,当且仅当key不存在。若给定的key已经存在,则SETNX不做任何动作。设置成功,返回1。设置失败,返回0。///</summary>///<paramname="key">关键字</param>///<paramname="value">数据值</param>///<returns>设置成功,返回1。设置失败,返回0。</returns>publicOperateResult<int>WriteKeyIfNotExists(stringkey,stringvalue){returnOperateNumberFromServer(newstring[]{"SETNX",key,value});}///<summary>///用value参数覆写(overwrite)给定key所储存的字符串值,从偏移量offset开始。不存在的key当作空白字符串处理。返回被SETRANGE修改之后,字符串的长度。///</summary>///<paramname="key">关键字</param>///<paramname="value">数值</param>///<paramname="offset">起始的偏移量</param>///<returns>被SETRANGE修改之后,字符串的长度。</returns>publicOperateResult<int>WriteKeyRange(stringkey,stringvalue,intoffset){returnOperateNumberFromServer(newstring[]{"SETRANGE",key,offset.ToString(),value});}///<summary>///返回key所储存的字符串值的长度。当key储存的不是字符串值时,返回一个错误。返回符串值的长度。当key不存在时,返回0。///</summary>///<paramname="key">关键字</param>///<returns>字符串值的长度。当key不存在时,返回0。</returns>publicOperateResult<int>ReadKeyLength(stringkey){returnOperateNumberFromServer(newstring[]{"STRLEN",key});}#endregion#regionListOperate///<summary>///将值value插入到列表key当中,位于值pivot之前。///当pivot不存在于列表key时,不执行任何操作。///当key不存在时,key被视为空列表,不执行任何操作。///如果key不是列表类型,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="value">数值</param>///<paramname="pivot">原先的值</param>///<returns>///如果命令执行成功,返回插入操作完成之后,列表的长度。///如果没有找到pivot,返回-1。///如果key不存在或为空列表,返回0。///</returns>publicOperateResult<int>ListInsertBefore(stringkey,stringvalue,stringpivot){returnOperateNumberFromServer(newstring[]{"LINSERT",key,"BEFORE",pivot,value});}///<summary>///将值value插入到列表key当中,位于值pivot之后。///当pivot不存在于列表key时,不执行任何操作。///当key不存在时,key被视为空列表,不执行任何操作。///如果key不是列表类型,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="value">数值</param>///<paramname="pivot">原先的值</param>///<returns>///如果命令执行成功,返回插入操作完成之后,列表的长度。///如果没有找到pivot,返回-1。///如果key不存在或为空列表,返回0。///</returns>publicOperateResult<int>ListInsertAfter(stringkey,stringvalue,stringpivot){returnOperateNumberFromServer(newstring[]{"LINSERT",key,"AFTER",pivot,value});}///<summary>///返回列表key的长度。如果key不存在,则key被解释为一个空列表,返回0.如果key不是列表类型,返回一个错误。///</summary>///<paramname="key">关键字</param>///<returns>列表key的长度。</returns>publicOperateResult<int>GetListLength(stringkey){returnOperateNumberFromServer(newstring[]{"LLEN",key});}///<summary>///返回列表key中,下标为index的元素。下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。///你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。如果key不是列表类型,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="index">索引位置</param>///<returns>列表中下标为index的元素。如果index参数的值不在列表的区间范围内(outofrange),返回nil。</returns>publicOperateResult<string>ReadListByIndex(stringkey,longindex){returnOperateStringFromServer(newstring[]{"LINDEX",key,index.ToString()});}///<summary>///移除并返回列表key的头元素。列表的头元素。当key不存在时,返回nil。///</summary>///<paramname="key">关键字信息</param>///<returns>列表的头元素。</returns>publicOperateResult<string>ListLeftPop(stringkey){returnOperateStringFromServer(newstring[]{"LPOP",key});}///<summary>///将一个或多个值value插入到列表key的表头,如果key不存在,一个空列表会被创建并执行LPUSH操作。当key存在但不是列表类型时,返回一个错误。返回执行LPUSH命令后,列表的长度。///</summary>///<paramname="key">关键字</param>///<paramname="value">值</param>///<returns>执行LPUSH命令后,列表的长度。</returns>publicOperateResult<int>ListLeftPush(stringkey,stringvalue){returnListLeftPush(key,newstring[]{value});}///<summary>///将一个或多个值value插入到列表key的表头,如果key不存在,一个空列表会被创建并执行LPUSH操作。当key存在但不是列表类型时,返回一个错误。返回执行LPUSH命令后,列表的长度。///</summary>///<paramname="key">关键字</param>///<paramname="values">值</param>///<returns>执行LPUSH命令后,列表的长度。</returns>publicOperateResult<int>ListLeftPush(stringkey,string[]values){List<string>list=newList<string>();list.Add("LPUSH");list.Add(key);list.AddRange(values);returnOperateNumberFromServer(list.ToArray());}///<summary>///将值value插入到列表key的表头,当且仅当key存在并且是一个列表。和LPUSH命令相反,当key不存在时,LPUSHX命令什么也不做。///返回LPUSHX命令执行之后,表的长度。///</summary>///<paramname="key">关键字</param>///<paramname="value">值</param>///<returns>是否插入数据成功</returns>publicOperateResult<int>ListLeftPushX(stringkey,stringvalue){returnOperateNumberFromServer(newstring[]{"LPUSHX",key,value});}///<summary>///返回列表key中指定区间内的元素,区间以偏移量start和stop指定。///下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。///你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。///返回一个列表,包含指定区间内的元素。///</summary>///<paramname="key">关键字</param>///<paramname="start">开始的索引</param>///<paramname="stop">结束的索引</param>///<returns>返回一个列表,包含指定区间内的元素。</returns>publicOperateResult<string[]>ListRange(stringkey,longstart,longstop){returnOperateStringsFromServer(newstring[]{"LRANGE",key,start.ToString(),stop.ToString()});}///<summary>///根据参数count的值,移除列表中与参数value相等的元素。count的值可以是以下几种:///count>0:从表头开始向表尾搜索,移除与value相等的元素,数量为count。///count<0:从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值。///count=0:移除表中所有与value相等的值。///返回被移除的数量。///</summary>///<paramname="key">关键字</param>///<paramname="count">移除参数</param>///<paramname="value">匹配的值</param>///<returns>被移除元素的数量。因为不存在的key被视作空表(emptylist),所以当key不存在时,LREM命令总是返回0。</returns>publicOperateResult<int>ListRemoveElementMatch(stringkey,longcount,stringvalue){returnOperateNumberFromServer(newstring[]{"LREM",key,count.ToString(),value});}///<summary>///设置数组的某一个索引的数据信息,当index参数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="index">索引位置</param>///<paramname="value">值</param>///<returns>操作成功返回ok,否则返回错误信息。</returns>publicOperateResultListSet(stringkey,longindex,stringvalue){returnOperateStatusFromServer(newstring[]{"LSET",key.ToString(),index.ToString(),value});}///<summary>///对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。///举个例子,执行命令LTRIMlist02,表示只保留列表list的前三个元素,其余元素全部删除。///下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。///你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。///当key不是列表类型时,返回一个错误。///</summary>///<paramname="key">关键字信息</param>///<paramname="start">起始的索引信息</param>///<paramname="end">结束的索引信息</param>///<returns>操作成功返回ok,否则返回错误信息。</returns>publicOperateResultListTrim(stringkey,longstart,longend){returnOperateStatusFromServer(newstring[]{"LTRIM",key,start.ToString(),end.ToString()});}///<summary>///移除并返回列表key的尾元素。当key不存在时,返回nil。///</summary>///<paramname="key">关键字信息</param>///<returns>列表的尾元素。</returns>publicOperateResult<string>ListRightPop(stringkey){returnOperateStringFromServer(newstring[]{"RPOP",key});}///<summary>///命令RPOPLPUSH在一个原子时间内,执行以下两个动作:///1.将列表source中的最后一个元素(尾元素)弹出,并返回给客户端。///2.将source弹出的元素插入到列表destination,作为destination列表的的头元素。///举个例子,你有两个列表source和destination,source列表有元素a,b,c,destination列表有元素x,y,z,执行RPOPLPUSHsourcedestination之后,source列表包含元素a,b,destination列表包含元素c,x,y,z,并且元素c会被返回给客户端。///如果source不存在,值nil被返回,并且不执行其他动作。///如果source和destination相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。///</summary>///<paramname="key1">第一个关键字</param>///<paramname="key2">第二个关键字</param>///<returns>返回的移除的对象</returns>publicOperateResult<string>ListRightPopLeftPush(stringkey1,stringkey2){returnOperateStringFromServer(newstring[]{"RPOPLPUSH",key1,key2});}///<summary>///将一个或多个值value插入到列表key的表尾(最右边)。///如果key不存在,一个空列表会被创建并执行RPUSH操作。当key存在但不是列表类型时,返回一个错误。///</summary>///<paramname="key">关键字</param>///<paramname="value">值</param>///<returns>返回执行RPUSH操作后,表的长度。</returns>publicOperateResult<int>ListRightPush(stringkey,stringvalue){returnListRightPush(key,newstring[]{value});}///<summary>///将一个或多个值value插入到列表key的表尾(最右边)。///如果有多个value值,那么各个value值按从左到右的顺序依次插入到表尾:比如对一个空列表mylist执行RPUSHmylistabc,得出的结果列表为abc,///如果key不存在,一个空列表会被创建并执行RPUSH操作。当key存在但不是列表类型时,返回一个错误。///返回执行RPUSH操作后,表的长度。///</summary>///<paramname="key">关键字</param>///<paramname="values">值</param>///<returns>返回执行RPUSH操作后,表的长度。</returns>publicOperateResult<int>ListRightPush(stringkey,string[]values){List<string>list=newList<string>();list.Add("RPUSH");list.Add(key);list.AddRange(values);returnOperateNumberFromServer(list.ToArray());}///<summary>///将值value插入到列表key的表尾,当且仅当key存在并且是一个列表。///和RPUSH命令相反,当key不存在时,RPUSHX命令什么也不做。///</summary>///<paramname="key">关键字</param>///<paramname="value">值</param>///<returns>RPUSHX命令执行之后,表的长度。</returns>publicOperateResult<int>ListRightPushX(stringkey,stringvalue){returnOperateNumberFromServer(newstring[]{"RPUSHX",key,value});}#endregion#regionHashOperate///<summary>///删除哈希表key中的一个或多个指定域,不存在的域将被忽略。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<returns>被成功移除的域的数量,不包括被忽略的域。</returns>publicOperateResult<int>DeleteHashKey(stringkey,stringfield){returnDeleteHashKey(key,newstring[]{field});}///<summary>///删除哈希表key中的一个或多个指定域,不存在的域将被忽略。返回被成功移除的域的数量,不包括被忽略的域。///</summary>///<paramname="key">关键字</param>///<paramname="fields">所有的域</param>///<returns>返回被成功移除的域的数量,不包括被忽略的域。</returns>publicOperateResult<int>DeleteHashKey(stringkey,string[]fields){List<string>list=newList<string>();list.Add("HDEL");list.Add(key);list.AddRange(fields);returnOperateNumberFromServer(list.ToArray());}///<summary>///查看哈希表key中,给定域field是否存在。如果哈希表含有给定域,返回1。///如果哈希表不含有给定域,或key不存在,返回0。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<returns>如果哈希表含有给定域,返回1。如果哈希表不含有给定域,或key不存在,返回0。</returns>publicOperateResult<int>ExistsHashKey(stringkey,stringfield){returnOperateNumberFromServer(newstring[]{"HEXISTS",key,field});}///<summary>///返回哈希表key中给定域field的值。当给定域不存在或是给定key不存在时,返回nil///</summary>///<paramname="key">关键值</param>///<paramname="field">域</param>///<returns>///给定域的值。///当给定域不存在或是给定key不存在时,返回nil。///</returns>publicOperateResult<string>ReadHashKey(stringkey,stringfield){returnOperateStringFromServer(newstring[]{"HGET",key,field});}///<summary>///返回哈希表key中,所有的域和值。在返回值里,紧跟每个域名(fieldname)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。///</summary>///<paramname="key">关键值</param>///<returns>///以列表形式返回哈希表的域和域的值。///若key不存在,返回空列表。///</returns>publicOperateResult<string[]>ReadHashKeyAll(stringkey){returnOperateStringsFromServer(newstring[]{"HGETALL",key});}///<summary>///为哈希表key中的域field的值加上增量increment。增量也可以为负数,相当于对给定域进行减法操作。///如果key不存在,一个新的哈希表被创建并执行HINCRBY命令。返回执行HINCRBY命令之后,哈希表key中域field的值。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<paramname="value">增量值</param>///<returns>返回执行HINCRBY命令之后,哈希表key中域field的值。</returns>publicOperateResult<long>IncrementHashKey(stringkey,stringfield,longvalue){returnOperateLongNumberFromServer(newstring[]{"HINCRBY",key,field,value.ToString()});}///<summary>///为哈希表key中的域field的值加上增量increment。增量也可以为负数,相当于对给定域进行减法操作。///如果key不存在,一个新的哈希表被创建并执行HINCRBY命令。返回执行HINCRBY命令之后,哈希表key中域field的值。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<paramname="value">增量值</param>///<returns>返回执行HINCRBY命令之后,哈希表key中域field的值。</returns>publicOperateResult<string>IncrementHashKey(stringkey,stringfield,floatvalue){returnOperateStringFromServer(newstring[]{"HINCRBYFLOAT",key,field,value.ToString()});}///<summary>///返回哈希表key中的所有域。当key不存在时,返回一个空表。///</summary>///<paramname="key">关键值</param>///<returns>///一个包含哈希表中所有域的表。///当key不存在时,返回一个空表。///</returns>publicOperateResult<string[]>ReadHashKeys(stringkey){returnOperateStringsFromServer(newstring[]{"HKEYS",key});}///<summary>///返回哈希表key中域的数量。///</summary>///<paramname="key">关键字</param>///<returns>哈希表中域的数量。当key不存在时,返回0。</returns>publicOperateResult<int>ReadHashKeyLength(stringkey){returnOperateNumberFromServer(newstring[]{"HLEN",key});}///<summary>///返回哈希表key中,一个或多个给定域的值。如果给定的域不存在于哈希表,那么返回一个nil值。///因为不存在的key被当作一个空哈希表来处理,所以对一个不存在的key进行HMGET操作将返回一个只带有nil值的表。///</summary>///<paramname="key">关键值</param>///<paramname="fields">指定的域</param>///<returns>///一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。///</returns>publicOperateResult<string[]>ReadHashKey(stringkey,string[]fields){List<string>list=newList<string>();list.Add("HMGET");list.Add(key);list.AddRange(fields);returnOperateStringsFromServer(list.ToArray());}///<summary>///将哈希表key中的域field的值设为value。///如果key不存在,一个新的哈希表被创建并进行HSET操作。///如果域field已经存在于哈希表中,旧值将被覆盖。///如果field是哈希表中的一个新建域,并且值设置成功,返回1。///如果哈希表中域field已经存在且旧值已被新值覆盖,返回0。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<paramname="value">数据值</param>///<returns>///如果field是哈希表中的一个新建域,并且值设置成功,返回1。///如果哈希表中域field已经存在且旧值已被新值覆盖,返回0。///</returns>publicOperateResult<int>WriteHashKey(stringkey,stringfield,stringvalue){returnOperateNumberFromServer(newstring[]{"HSET",key,field,value});}///<summary>///同时将多个field-value(域-值)对设置到哈希表key中。///此命令会覆盖哈希表中已存在的域。///如果key不存在,一个空哈希表被创建并执行HMSET操作。///</summary>///<paramname="key">关键字</param>///<paramname="fields">域</param>///<paramname="values">数据值</param>///<returns>///如果命令执行成功,返回OK。///当key不是哈希表(hash)类型时,返回一个错误///</returns>publicOperateResultWriteHashKey(stringkey,string[]fields,string[]values){if(fields==null)thrownewArgumentNullException("fields");if(values==null)thrownewArgumentNullException("values");if(fields.Length!=values.Length)thrownewArgumentException("Two arguement not same length");List<string>list=newList<string>();list.Add("HMSET");list.Add(key);for(inti=0;i<fields.Length;i++){list.Add(fields[i]);list.Add(values[i]);}returnOperateStatusFromServer(list.ToArray());}///<summary>///将哈希表key中的域field的值设置为value,当且仅当域field不存在。若域field已经存在,该操作无效。///设置成功,返回1。如果给定域已经存在且没有操作被执行,返回0。///</summary>///<paramname="key">关键字</param>///<paramname="field">域</param>///<paramname="value">数据值</param>///<returns>设置成功,返回1。如果给定域已经存在且没有操作被执行,返回0。</returns>publicOperateResult<int>WriteHashKeyNx(stringkey,stringfield,stringvalue){returnOperateNumberFromServer(newstring[]{"HSETNX",key,field,value});}///<summary>///返回哈希表key中所有域的值。当key不存在时,返回一个空表。///</summary>///<paramname="key">关键值</param>///<returns>///返回哈希表key中所有域的值。///当key不存在时,返回一个空表。///</returns>publicOperateResult<string[]>ReadHashValues(stringkey){returnOperateStringsFromServer(newstring[]{"HVALS",key});}#endregion#regionServerOperate///<summary>///SAVE命令执行一个同步保存操作,将当前Redis实例的所有数据快照(snapshot)以RDB文件的形式保存到硬盘。///</summary>///<returns>保存成功时返回OK。</returns>publicOperateResultSave(){returnOperateStatusFromServer(newstring[]{"SAVE"});}///<summary>///在后台异步(Asynchronously)保存当前数据库的数据到磁盘。///BGSAVE命令执行之后立即返回OK,然后Redisfork出一个新子进程,原来的Redis进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。///</summary>///<returns>反馈信息。</returns>publicOperateResultSaveAsync(){returnOperateStatusFromServer(newstring[]{"BGSAVE"});}///<summary>///获取服务器的时间戳信息,可用于本地时间的数据同步问题///</summary>///<returns>带有服务器时间的结果对象</returns>publicOperateResult<DateTime>ReadServerTime(){OperateResult<string[]>times=OperateStringsFromServer(newstring[]{"TIME"});if(!times.IsSuccess)returnOperateResult.CreateFailedResult<DateTime>(times);longtimeTick=long.Parse(times.Content[0]);DateTimedateTime=newDateTime(1970,1,1,8,0,0).AddSeconds(timeTick);returnOperateResult.CreateSuccessResult(dateTime);}#endregion#regionPublish///<summary>///将信息message发送到指定的频道channel,返回接收到信息message的订阅者数量。///</summary>///<paramname="channel">频道,和关键字不是一回事</param>///<paramname="message">消息</param>///<returns>接收到信息message的订阅者数量。</returns>publicOperateResult<int>Publish(stringchannel,stringmessage){returnOperateNumberFromServer(newstring[]{"PUBLISH",channel,message});}#endregion#regionDBBlock///<summary>///切换到指定的数据库,数据库索引号index用数字值指定,以0作为起始索引值。默认使用0号数据库。///</summary>///<paramname="db">索引值</param>///<returns>是否切换成功</returns>publicOperateResultSelectDB(intdb){returnOperateStatusFromServer(newstring[]{"SELECT",db.ToString()});}#endregion#regionPrivateMemberprivatestringpassword=string.Empty;//密码信息#endregion#regionObjectOverride///<summary>///返回表示当前对象的字符串///</summary>///<returns>字符串信息</returns>publicoverridestringToString(){return$"RedisClient[{IpAddress}:{Port}]";}#endregion}}