public static string SendRequest(this ConnectorBase connector, string serviceName, ServiceDetailsMethod serviceDetailMethod, out string json)
        {
            MethodCallInfo callInfo = new MethodCallInfo()
            {
                ServiceName = serviceName,
                MethodName  = serviceDetailMethod.MethodName
            };

            foreach (var item in serviceDetailMethod.Parameters)
            {
                callInfo.Parameters.Add(new Shared.Models.ParameterInfo()
                {
                    Value = item.Value.ToString(), Type = item.FullTypeName
                });
            }

            var guid = Guid.NewGuid().ToString();

            callInfo.Guid = guid;
            var added = WaitedMethodsForResponse.TryAdd(callInfo.Guid, new KeyValue <AutoResetEvent, MethodCallbackInfo>(new AutoResetEvent(false), null));

            //var service = connector.Services.ContainsKey(callInfo.ServiceName) ? connector.Services[callInfo.ServiceName] : null;
            //var method = service == null ? null : service.GetType().GetMethod(callInfo.MethodName, RuntimeTypeHelper.GetMethodTypes(service.GetType(), callInfo).ToArray());
            json = JsonConvert.SerializeObject(callInfo);
            connector.SendData(callInfo);


            var seted = WaitedMethodsForResponse[callInfo.Guid].Key.WaitOne(connector.ProviderSetting.SendDataTimeout);

            if (!seted)
            {
                if (connector.SettingInfo != null && connector.SettingInfo.IsDisposeClientWhenTimeout)
                {
                    connector.Dispose();
                }
                throw new TimeoutException();
            }
            var result = WaitedMethodsForResponse[callInfo.Guid].Value;

            if (callInfo.MethodName == "/RegisterService")
            {
                connector.SessionId = JsonConvert.DeserializeObject <string>(result.Data);
                result.Data         = null;
            }
            WaitedMethodsForResponse.Remove(callInfo.Guid);
            if (result == null)
            {
                if (connector.IsDisposed)
                {
                    throw new Exception("client disconnected");
                }
                return("disposed");
            }
            if (result.IsException)
            {
                throw new Exception("server exception:" + JsonConvert.DeserializeObject <string>(result.Data));
            }
            else if (result.IsAccessDenied && result.Data == null)
            {
                throw new Exception("server permission denied exception.");
            }

            return(result.Data);
        }
        static object SendData(this ConnectorBase connector, MethodCallInfo callInfo, StreamInfo streamInfo)
        {
            var added   = WaitedMethodsForResponse.TryAdd(callInfo.Guid, new KeyValue <AutoResetEvent, MethodCallbackInfo>(new AutoResetEvent(false), null));
            var service = connector.Services.ContainsKey(callInfo.ServiceName) ? connector.Services[callInfo.ServiceName] : null;
            var method  = service?.GetType().GetMethod(callInfo.MethodName, RuntimeTypeHelper.GetMethodTypes(service.GetType(), callInfo).ToArray());

            if (method != null && method.ReturnType == typeof(StreamInfo))
            {
                callInfo.Data = connector.SessionId;
                StreamInfo stream = connector.RegisterFileStreamToDownload(callInfo);
                return(stream);
            }
            else if (method != null && streamInfo != null && method.ReturnType == typeof(void) && method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(StreamInfo))
            {
                callInfo.Data = connector.SessionId;
                connector.RegisterFileStreamToUpload(streamInfo, callInfo);
                return(null);
            }
            else
            {
                connector.SendData(callInfo);
            }


            var seted = WaitedMethodsForResponse[callInfo.Guid].Key.WaitOne(connector.ProviderSetting.SendDataTimeout);

            if (!seted)
            {
                if (connector.SettingInfo != null && connector.SettingInfo.IsDisposeClientWhenTimeout)
                {
                    connector.Dispose();
                }
                throw new TimeoutException();
            }
            var result = WaitedMethodsForResponse[callInfo.Guid].Value;

            if (callInfo.MethodName == "/RegisterService")
            {
                connector.SessionId = JsonConvert.DeserializeObject <string>(result.Data);
                result.Data         = null;
            }
            WaitedMethodsForResponse.Remove(callInfo.Guid);
            if (result == null)
            {
                if (connector.IsDisposed)
                {
                    throw new Exception("client disconnected");
                }
                return(null);
            }
            if (result.IsException)
            {
                throw new Exception("server exception:" + JsonConvert.DeserializeObject <string>(result.Data));
            }
            else if (result.IsAccessDenied && result.Data == null)
            {
                throw new Exception("server permission denied exception.");
            }

            return(result.Data);
        }