Esempio n. 1
0
        /// <summary>
        /// 发送命令给服务器
        /// </summary>
        /// <param name="ns"></param>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private bool Send(NetworkStream ns, RedisCommand cmd)
        {
            // 取得内存流对象
            var ms = Cache.Get();

            if (ms == null)
            {
                throw new RedisClientException(Cache.Message, MethodBase.GetCurrentMethod());
            }

            // 制作命令包并将其写入内存流
            // 说明:Redis的管道(pipelining)技术就是将不同命令打包在一起批量发送。
            // 参考:https://redis.io/topics/pipelining
            try
            {
                // 取得并写入命令和参数,示例:*2\r\n$4\r\nLLEN\r\n$6\r\nmylist\r\n
                foreach (var obj in cmd.Value)
                {
                    if (obj is byte[] byts)
                    {
                        ms.Write(byts, 0, byts.Length);
                    }
                }
            }
            catch (Exception e)
            {
                throw new RedisClientException($"创建命令{ObjectConvert.C2Str(cmd.Command)}失败({e.Message})", MethodBase.GetCurrentMethod(), ObjectConvert.C2Str(ms.ToArray()));
            }

            // 尝试将内存流写入到网络流发送给服务器
            try
            {
                ms.WriteTo(ns);
            }
            catch (Exception e)
            {
                throw new RedisClientException($"发送命令{ObjectConvert.C2Str(cmd.Command)}失败({e.Message})", MethodBase.GetCurrentMethod(), ObjectConvert.C2Str(ms.ToArray()));
            }
            finally
            {
                // 归还内存流对象
                Cache.Put(ms);
            }

            // 返回
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// 尝试将结果转换成目标类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="result"></param>
        /// <returns></returns>
        private T TryConvertType <T>(object result)
        {
            // 取第一项
            object value;

            if (result is IList <object> rs)
            {
                value = rs.FirstOrDefault();
            }
            else
            {
                value = result;
            }

            // 转换字符串
            if (value is string str)
            {
                try
                {
                    switch (str)
                    {
                    case "OK": return((T)Commands.Ok);

                    case "PONG": return((T)Commands.Ok);
                    }
                    return(TypeConvert.C2Type <T>(str));
                }
                catch (Exception e)
                {
                    throw new RedisClientException($"将字符串({value})转为类型({typeof(T).Name})失败({e.Message})", MethodBase.GetCurrentMethod());
                }
            }

            // 转换字节
            if (value is byte[] byts)
            {
                try
                {
                    object   retVal;
                    TypeCode typeCode = Type.GetTypeCode(typeof(T));
                    switch (typeCode)
                    {
                    case TypeCode.Object: retVal = ObjectConvert.C2Obj <T>(byts); break;

                    case TypeCode.String: retVal = ObjectConvert.C2Str(byts); break;

                    case TypeCode.DateTime: retVal = ObjectConvert.C2Date(byts); break;

                    case TypeCode.Decimal: retVal = ObjectConvert.C2Dec(byts); break;

                    case TypeCode.Double: retVal = ObjectConvert.C2Dbl(byts); break;

                    case TypeCode.Single: retVal = ObjectConvert.C2Flt(byts); break;

                    case TypeCode.Int64: retVal = ObjectConvert.C2Lng(byts); break;

                    case TypeCode.Int32: retVal = ObjectConvert.C2Int(byts); break;

                    case TypeCode.Int16: retVal = ObjectConvert.C2Short(byts); break;

                    case TypeCode.UInt64: retVal = ObjectConvert.C2Lng(byts); break;

                    case TypeCode.UInt32: retVal = ObjectConvert.C2Int(byts); break;

                    case TypeCode.UInt16: retVal = ObjectConvert.C2Short(byts); break;

                    case TypeCode.Byte: retVal = ObjectConvert.C2Byte(byts); break;

                    case TypeCode.SByte: retVal = ObjectConvert.C2SByte(byts); break;

                    case TypeCode.Char: retVal = ObjectConvert.C2Chr(byts); break;

                    case TypeCode.Boolean: retVal = ObjectConvert.C2Bool(byts); break;

                    default: retVal = TypeConvert.C2Type <T>(byts); break;
                    }
                    return((T)retVal);
                }
                catch (Exception e)
                {
                    throw new RedisClientException($"将结果转换成类型({typeof(T).Name})失败({e.Message})", MethodBase.GetCurrentMethod());
                }
            }

            return(default);