Ejemplo n.º 1
0
        private static async void SendCallbackData(Task <MethodCallbackInfo> callback, ClientInfo client, ServerBase serverBase)
#endif
        {
            try
            {
#if (NET35 || NET40)
                MethodCallbackInfo callbackResult = callback.Result;
#else
                MethodCallbackInfo callbackResult = await callback;
#endif
                string      json   = ServerSerializationHelper.SerializeObject(callbackResult, serverBase);
                byte[]      bytes  = Encoding.UTF8.GetBytes(json);
                List <byte> result = new List <byte>();
                result.Add((byte)DataType.ResponseCallMethod);
                result.Add((byte)CompressMode.None);

                result.AddRange(BitConverter.GetBytes(bytes.Length));
                result.AddRange(bytes);

                await client.StreamHelper.WriteToStreamAsync(client.ClientStream, result.ToArray());
            }
            catch (Exception ex)
            {
                serverBase.AutoLogger.LogError(ex, $"{client.IPAddress} {client.ClientId} ServerBase SendCallbackData");
                //if (!client.TcpClient.Connected)
                //    serverBase.DisposeClient(client, "SendCallbackData exception");
            }
            finally
            {
                //ClientConnectedCallingCount--;
            }
        }
Ejemplo n.º 2
0
        internal static async Task RunMethod(ServerBase serverBase, ClientInfo client)
        {
            MethodCallbackInfo callback = null;

            try
            {
                byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(client.ClientStream, CompressMode.None, serverBase.ProviderSetting.MaximumReceiveStreamHeaderBlock);

                string         json     = Encoding.UTF8.GetString(bytes);
                MethodCallInfo callInfo = ServerSerializationHelper.Deserialize <MethodCallInfo>(json, serverBase);
                //MethodsCallHandler.BeginStreamCallAction?.Invoke(client, guid, serviceName, methodName, values);
                CallMethodResultInfo <OperationContext> result = await CallMethod(callInfo.ServiceName, callInfo.Guid, callInfo.MethodName, callInfo.Parameters, null, client, null, serverBase, null, null);

                callback = result.CallbackInfo;
            }
            catch (Exception ex)
            {
                callback = new MethodCallbackInfo
                {
                    IsException = true,
                    Data        = ServerSerializationHelper.SerializeObject(ex)
                };
            }
            finally
            {
                //MethodsCallHandler.EndStreamCallAction?.Invoke(client, guid, serviceName, methodName, values, jsonResult, exception);
            }
            await SendCallbackData(callback, client, serverBase);
        }
        /// <summary>
        /// this method call when client want to upload file or stream to your server
        /// </summary>
        /// <param name="stream">client stream</param>
        /// <param name="client">client</param>
        private static async Task DownloadStreamFromClient(ClientInfo client, ServerBase serverBase)
        {
            MethodCallbackInfo callback = null;
            string             guid     = Guid.NewGuid().ToString();

            try
            {
                byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(client.ClientStream, CompressMode.None, serverBase.ProviderSetting.MaximumReceiveStreamHeaderBlock);

                string         json     = Encoding.UTF8.GetString(bytes);
                MethodCallInfo callInfo = ServerSerializationHelper.Deserialize <MethodCallInfo>(json, serverBase);

                CallMethodResultInfo <OperationContext> result = await CallMethod(callInfo.ServiceName, callInfo.Guid, callInfo.MethodName,
                                                                                  callInfo.Parameters, null, client, null, serverBase, null, null);

                callback = result.CallbackInfo;
            }
            catch (IOException ex)
            {
                callback             = new MethodCallbackInfo();
                callback.IsException = true;
                callback.Data        = ServerSerializationHelper.SerializeObject(ex);
                //return;
            }
            catch (Exception ex)
            {
                callback             = new MethodCallbackInfo();
                callback.IsException = true;
                callback.Data        = ServerSerializationHelper.SerializeObject(ex);
            }
            finally
            {
            }
            await SendCallbackData(callback, client, serverBase);
        }
Ejemplo n.º 4
0
        internal static async Task <T> SendWebSocketDataWithCallClientServiceMethod <T>(ServerBase serverBase, ClientInfo client, Type returnType, string serviceName, string methodName, params Shared.Models.ParameterInfo[] args)
        {
            if (returnType == null || returnType == typeof(void))
            {
                returnType = typeof(object);
            }
            else if (returnType.GetBaseType() == typeof(Task))
            {
                returnType = returnType.GetGenericArguments()[0];
            }

            if (methodName.LastIndexOf("Async", StringComparison.OrdinalIgnoreCase) == methodName.Length - 5)
            {
                methodName = methodName.Substring(0, methodName.Length - 5);
            }
#if (NET35 || NET40)
            return(null);// Task<object>.Factory.StartNew(run);
#else
            Type           type = typeof(TaskCompletionSource <>).MakeGenericType(returnType);
            object         taskCompletionSource = Activator.CreateInstance(type);
            MethodCallInfo callInfo             = new MethodCallInfo();
            callInfo.ServiceName = serviceName;
            callInfo.MethodName  = methodName;
            callInfo.Parameters  = args;
            string guid = Guid.NewGuid().ToString();
            callInfo.Guid = guid;
            serverBase.ClientServiceCallMethodsResult.TryAdd(guid, new KeyValue <Type, object>(returnType, taskCompletionSource));

            string json = ServerSerializationHelper.SerializeObject(callInfo, serverBase);
            ///when length is large we need to send data by parts
            if (json.Length > 30000)
            {
                List <string> listOfParts = WebSocketProvider.GeneratePartsOfData(json);
                int           i           = 1;
                foreach (string item in listOfParts)
                {
                    MethodCallInfo cb = callInfo.Clone();
                    cb.PartNumber = i == listOfParts.Count ? (short)-1 : (short)i;
                    json          = (int)DataType.CallMethod + "," + (int)CompressMode.None + "/" + ServerSerializationHelper.SerializeObject(cb, serverBase);
                    byte[] bytes = Encoding.UTF8.GetBytes(json);
                    await client.StreamHelper.WriteToStreamAsync(client.ClientStream, bytes);

                    i++;
                }
            }
            else
            {
                json = (int)DataType.CallMethod + "," + (int)CompressMode.None + "/" + json;
                byte[] bytes = Encoding.UTF8.GetBytes(json);
                await client.StreamHelper.WriteToStreamAsync(client.ClientStream, bytes);
            }
            object value  = taskCompletionSource.GetType().GetProperty("Task").GetValue(taskCompletionSource, null);
            T      result = await(Task <T>) value;
            return(result);
#endif
        }
Ejemplo n.º 5
0
        public override StreamInfo RegisterFileToDownload(NetworkStream stream, CompressMode compressMode, ClientInfo client, bool isWebSocket)
        {
            var            bytes    = GoStreamReader.ReadBlockToEnd(stream, compressMode, ProviderSetting.MaximumReceiveDataBlock, isWebSocket);
            var            json     = Encoding.UTF8.GetString(bytes);
            MethodCallInfo callInfo = ServerSerializationHelper.Deserialize <MethodCallInfo>(json);

            MethodCallbackInfo callback = new MethodCallbackInfo();

            callback.Guid = callInfo.Guid;

            var serviceType = RegisteredServiceTypes[callInfo.ServiceName];
            var sessionId   = callInfo.Data.ToString();
            var clientInfo  = (from x in Services.ToArray() where x.Key.SessionId == sessionId select x.Key).FirstOrDefault();

            if (clientInfo == null)
            {
                throw new Exception("RegisterFile client not found!");
            }
            var service = FindClientServiceByType(clientInfo, serviceType);

#if (NETSTANDARD1_6 || NETCOREAPP1_1)
            var method = serviceType.GetTypeInfo().GetMethod(callInfo.MethodName, RuntimeTypeHelper.GetMethodTypes(serviceType, callInfo).ToArray());
#else
            var method = serviceType.GetMethod(callInfo.MethodName, RuntimeTypeHelper.GetMethodTypes(serviceType, callInfo).ToArray());
#endif
            List <object> parameters = new List <object>();
            int           index      = 0;
            var           prms       = method.GetParameters();
            foreach (var item in callInfo.Parameters)
            {
                parameters.Add(ServerSerializationHelper.Deserialize(item.Value, prms[index].ParameterType));
                index++;
            }
            if (method.ReturnType != typeof(StreamInfo))
            {
                throw new Exception("return type for upload must StreamInfo!");
            }
            else
            {
                StreamInfo data = null;
                data = (StreamInfo)method.Invoke(service, parameters.ToArray());
                if (data == null)
                {
                    throw new Exception($"StreamInfo cannot be null");
                }
                var streamReader = data.Stream;
                data.Stream   = null;
                callback.Data = ServerSerializationHelper.SerializeObject(data, this);
                SendCallbackData(callback, client);
                data.Stream = streamReader;
                return(data);
            }
        }
Ejemplo n.º 6
0
        private static async void SendCallbackData(Task <MethodCallbackInfo> callback, ClientInfo client, ServerBase serverBase)
#endif
        {
            try
            {
#if (NET35 || NET40)
                MethodCallbackInfo callbackResult = callback.Result;
#else
                MethodCallbackInfo callbackResult = await callback;
#endif
                string json = ServerSerializationHelper.SerializeObject(callbackResult, serverBase);
                if (json.Length > 5000)
                {
                    List <string> listOfParts = GeneratePartsOfData(json);
                    int           i           = 1;
                    foreach (string item in listOfParts)
                    {
                        MethodCallbackInfo cb = callbackResult.Clone();
                        cb.PartNumber = i == listOfParts.Count ? (short)-1 : (short)i;
                        cb.Data       = item;
                        json          = (int)DataType.ResponseCallMethod + "," + (int)CompressMode.None + "/" + ServerSerializationHelper.SerializeObject(cb, serverBase);
                        byte[] result = Encoding.UTF8.GetBytes(json);
                        //if (ClientsSettings.ContainsKey(client))
                        //    result = EncryptBytes(result, client);
                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, result);

                        i++;
                    }
                }
                else
                {
                    json = (int)DataType.ResponseCallMethod + "," + (int)CompressMode.None + "/" + json;
                    byte[] result = Encoding.UTF8.GetBytes(json);
                    //if (ClientsSettings.ContainsKey(client))
                    //    result = EncryptBytes(result, client);
                    await client.StreamHelper.WriteToStreamAsync(client.ClientStream, result);
                }
            }
            catch (Exception ex)
            {
                serverBase.AutoLogger.LogError(ex, $"{client.IPAddress} {client.ClientId} ServerBase SendCallbackData");
                //if (!client.TcpClient.Connected)
                //    serverBase.DisposeClient(client, "SendCallbackData exception");
            }
            finally
            {
                //ClientConnectedCallingCount--;
            }
        }
        static object SendDataNow(this OperationCalls client, string callerName, params object[] args)
        {
            if (SynchronizationContext.Current != null && ServerBase.AllDispatchers.ContainsKey(SynchronizationContext.Current) && ServerBase.AllDispatchers[SynchronizationContext.Current].MainContext == SynchronizationContext.Current)
            {
                throw new Exception("Cannot call method from class Constractor or main Thread");
            }
            var            attribute = client.GetType().GetCustomAttributes <ServiceContractAttribute>(true).FirstOrDefault();
            MethodCallInfo callInfo  = new MethodCallInfo();

            callInfo.ServiceName = attribute.Name;
            callInfo.MethodName  = callerName;
            foreach (var item in args)
            {
                callInfo.Parameters.Add(new Shared.Models.ParameterInfo()
                {
                    Value = item == null ? null : ServerSerializationHelper.SerializeObject(item, client.ServerBase), Type = item == null ? null : item.GetType().FullName
                });
            }
            var guid = Guid.NewGuid().ToString();

            callInfo.Guid = guid;
            var waitedMethodsForResponse = client.ServerBase.WaitedMethodsForResponse[client.CurrentClient];

            waitedMethodsForResponse.TryAdd(guid, new KeyValue <AutoResetEvent, MethodCallbackInfo>(new AutoResetEvent(false), null));
            client.ServerBase.CallClientMethod(client.CurrentClient, callInfo);
            var seted = waitedMethodsForResponse[guid].Key.WaitOne(client.ServerBase.ProviderSetting.SendDataTimeout);

            if (!seted)
            {
                client.ServerBase.CheckClient(client.CurrentClient);
                waitedMethodsForResponse.Remove(guid);
                throw new TimeoutException();
            }
            if (waitedMethodsForResponse[guid].Value.IsException)
            {
                var data = waitedMethodsForResponse[guid].Value.Data;
                waitedMethodsForResponse.Remove(guid);
                throw new Exception("method call exception: " + data);
            }
            var result = waitedMethodsForResponse[guid].Value.Data;

            waitedMethodsForResponse.Remove(guid);
            return(result);
        }
Ejemplo n.º 8
0
        //static ServerExtension()
        //{
        //    Init();
        //}

        //internal static void Init()
        //{
        //    CSCodeInjection.InvokedServerMethodAction = (client, method, parameters) =>
        //    {
        //        //Console.WriteLine($"CSCodeInjection.InvokedServerMethodAction {method.Name}");
        //        OperationCalls op = (OperationCalls)client;
        //        SendToClientDataInvoke(op, method.Name, parameters);
        //        //MethodsCallHandler.EndClientMethodCallAction?.Invoke(op.CurrentClient, null, method.Name, parameters, null, null);
        //    };

        //    CSCodeInjection.InvokedServerMethodFunction = (client, method, parameters) =>
        //    {
        //        //Console.WriteLine($"CSCodeInjection.InvokedServerMethodFunction {method.Name}");
        //        OperationCalls op = (OperationCalls)client;
        //        var data = SendToClientData((OperationCalls)client, method.Name, parameters);
        //        var result = ServerSerializationHelper.Deserialize(data.ToString(), method.ReturnType, ((OperationCalls)client).ServerBase);
        //        //MethodsCallHandler.EndClientMethodCallAction?.Invoke(op.CurrentClient, null, method.Name, parameters, result, null);
        //        return result;
        //    };
        //}

        //public static void RunOnDispatcher(this ClientInfo client, Action run)
        //{
        //    client.ServerBase.ClientDispatchers[client].Post((state) =>
        //    {
        //        run();
        //    }, null);
        //}

        //public static T SendData<T>(this OperationCalls client, string callerName, params object[] args)
        //{
        //    var data = SendToClientData(client, callerName, args);
        //    if (data == null || data.ToString() == "")
        //        return default(T);
        //    return ServerSerializationHelper.Deserialize<T>(data.ToString(), client.ServerBase);
        //}

        //public static void SendToClientDataInvoke(this OperationCalls client, string callerName, params object[] args)
        //{
        //    SendToClientData(client, callerName, args);
        //}

        //static object SendToClientData(this OperationCalls client, string callerName, params object[] args)
        //{
        //    var attribute = client.GetType().GetClientServiceAttribute();
        //    if (client.ServerBase.ClientRegistredMethods[client.CurrentClient].ContainsKey(attribute.Name))
        //    {
        //        if (client.ServerBase.ClientRegistredMethods[client.CurrentClient][attribute.Name].Contains(callerName))
        //        {
        //            return SendCallClientMethod(client, callerName, args);
        //        }
        //    }
        //    else if (client.ServerBase.RegisteredClientServicesTypes.ContainsKey(attribute.Name))
        //    {
        //        return SendCallClientMethod(client, callerName, args);
        //    }
        //    return null;
        //}

        //internal static object SendDataWithCallClientServiceMethod(ServerBase serverBase,ClientInfo client,string serviceName, string methodName, params Shared.Models.GoParameterInfo[] args)
        //{
        //    MethodCallInfo callInfo = new MethodCallInfo();
        //    callInfo.ServiceName = serviceName;
        //    callInfo.MethodName = methodName;
        //    callInfo.Parameters = args;
        //    var guid = Guid.NewGuid().ToString();
        //    callInfo.Guid = guid;
        //    var bytes = Encoding.UTF8.GetBytes(ServerSerializationHelper.SerializeObject(callInfo, serverBase));
        //    client.StreamHelper.WriteBlockToStream(client.ClientStream, bytes);
        //}

        internal static async Task <T> SendDataWithCallClientServiceMethod <T>(ServerBase serverBase, ClientInfo client, Type returnType, string serviceName, string methodName, params Shared.Models.ParameterInfo[] args)
        {
            if (returnType == null || returnType == typeof(void))
            {
                returnType = typeof(object);
            }
            //var method = typeof(ServerExtensions).GetMethod("SendDataWithCallClientServiceMethodGeneric").MakeGenericMethod(returnType);
            //Func<object> run = () =>
            //{
            //    return SendDataWithCallClientServiceMethodGeneric<int>(serverBase, client, returnType, serviceName, methodName, args);
            //};
            if (methodName.LastIndexOf("Async", StringComparison.OrdinalIgnoreCase) == methodName.Length - 5)
            {
                methodName = methodName.Substring(0, methodName.Length - 5);
            }
#if (NET35 || NET40)
            return(null);// Task<object>.Factory.StartNew(run);
#else
            Type           type = typeof(TaskCompletionSource <>).MakeGenericType(returnType);
            object         taskCompletionSource = Activator.CreateInstance(type);
            MethodCallInfo callInfo             = new MethodCallInfo();
            callInfo.ServiceName = serviceName;
            callInfo.MethodName  = methodName;
            callInfo.Parameters  = args;
            string guid = Guid.NewGuid().ToString();
            callInfo.Guid = guid;
            serverBase.ClientServiceCallMethodsResult.TryAdd(guid, new KeyValue <Type, object>(returnType, taskCompletionSource));
            List <byte> bytes = new List <byte>
            {
                (byte)DataType.CallMethod,
                (byte)CompressMode.None
            };
            byte[] jsonBytes = Encoding.UTF8.GetBytes(ServerSerializationHelper.SerializeObject(callInfo, serverBase));
            byte[] dataLen   = BitConverter.GetBytes(jsonBytes.Length);
            bytes.AddRange(dataLen);
            bytes.AddRange(jsonBytes);

            await client.StreamHelper.WriteToStreamAsync(client.ClientStream, bytes.ToArray());

            Task <T> result = (Task <T>)taskCompletionSource.GetType().GetProperty("Task").GetValue(taskCompletionSource, null);
            return(await result);
#endif
        }
        public static object CallClientCallbackMethod(this OperationCalls client, string methodName, params object[] values)
        {
            if (SynchronizationContext.Current != null && ServerBase.AllDispatchers.ContainsKey(SynchronizationContext.Current))
            {
                throw new Exception("Cannot call method from class Constractor or main Thread");
            }
            MethodCallInfo callInfo = new MethodCallInfo();

#if (NETSTANDARD1_6 || NETCOREAPP1_1)
            callInfo.ServiceName = ((ServiceContractAttribute)client.GetType().GetTypeInfo().GetCustomAttributes(typeof(ServiceContractAttribute), true).FirstOrDefault()).Name;
#else
            callInfo.ServiceName = ((ServiceContractAttribute)client.GetType().GetCustomAttributes(typeof(ServiceContractAttribute), true).FirstOrDefault()).Name;
#endif
            callInfo.MethodName = methodName;
            foreach (var item in values)
            {
                callInfo.Parameters.Add(new Shared.Models.ParameterInfo()
                {
                    Value = ServerSerializationHelper.SerializeObject(item, client.ServerBase), Type = item.GetType().FullName
                });
            }
            var guid = Guid.NewGuid().ToString();
            callInfo.Guid = guid;
            var waitedMethodsForResponse = client.ServerBase.WaitedMethodsForResponse[client.CurrentClient];
            waitedMethodsForResponse.TryAdd(guid, new KeyValue <AutoResetEvent, MethodCallbackInfo>(new AutoResetEvent(false), null));
            client.ServerBase.CallClientMethod(client.CurrentClient, callInfo);
            var seted = waitedMethodsForResponse[guid].Key.WaitOne(client.ServerBase.ProviderSetting.ReceiveDataTimeout);
            if (!seted)
            {
                client.ServerBase.CheckClient(client.CurrentClient);
                waitedMethodsForResponse.Remove(guid);
                throw new TimeoutException();
            }
            if (waitedMethodsForResponse[guid].Value.IsException)
            {
                var data = waitedMethodsForResponse[guid].Value.Data;
                waitedMethodsForResponse.Remove(guid);
                throw new Exception("call method return exception: " + data);
            }
            var result = waitedMethodsForResponse[guid].Value.Data;
            waitedMethodsForResponse.Remove(guid);
            return(result);
        }
Ejemplo n.º 10
0
        public static async Task StartToReadingClientData(ClientInfo client, ServerBase serverBase)
        {
            try
            {
                Console.WriteLine($"WebSocket Client Connected: {client.IPAddress}");
                Shared.IO.PipeNetworkStream stream = client.ClientStream;
                while (true)
                {
                    byte oneByteOfDataType = await client.StreamHelper.ReadOneByteAsync(stream);

                    //type of data
                    DataType dataType = (DataType)oneByteOfDataType;
                    if (dataType == DataType.PingPong)
                    {
                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, new byte[] { 5 });

                        continue;
                    }
                    //compress mode of data
                    CompressMode compressMode = (CompressMode)await client.StreamHelper.ReadOneByteAsync(stream);

                    //a server service method called from client
                    if (dataType == DataType.CallMethod)
                    {
                        string json = "";
                        //if (client.IsOwinClient)
                        //{
                        //    json = await stream.ReadLineAsync("#end");
                        //    if (json.EndsWith("#end"))
                        //        json = json.Substring(0, json.Length - 4);
                        //}
                        //else
                        //{
                        byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(stream, compressMode, serverBase.ProviderSetting.MaximumReceiveDataBlock);

                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = DecryptBytes(bytes, client);
                        json = Encoding.UTF8.GetString(bytes);
                        //}
                        MethodCallInfo callInfo = ServerSerializationHelper.Deserialize <MethodCallInfo>(json, serverBase);
                        if (callInfo.PartNumber != 0)
                        {
                            SegmentManager segmentManager = new SegmentManager();
                            ISegment       result         = segmentManager.GenerateAndMixSegments(callInfo);
                            if (result != null)
                            {
                                callInfo = (MethodCallInfo)result;
                            }
                            else
                            {
                                continue;
                            }
                        }
#if (NET35 || NET40)
                        MethodCallbackInfo callbackResult = CallMethod(callInfo, client, json, serverBase).Result;
                        SendCallbackData(callbackResult, client, serverBase);
#else
                        Task <MethodCallbackInfo> callbackResult = CallMethod(callInfo, client, json, serverBase);
                        SendCallbackData(callbackResult, client, serverBase);
#endif
                    }

                    //reponse of client method that server called to client
                    else if (dataType == DataType.ResponseCallMethod)
                    {
                        byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(stream, compressMode, serverBase.ProviderSetting.MaximumReceiveDataBlock);

                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = DecryptBytes(bytes, client);
                        string             json     = Encoding.UTF8.GetString(bytes);
                        MethodCallbackInfo callback = ServerSerializationHelper.Deserialize <MethodCallbackInfo>(json, serverBase);
                        if (callback == null)
                        {
                            serverBase.AutoLogger.LogText($"{client.IPAddress} {client.ClientId} callback is null:" + json);
                        }
                        if (callback.PartNumber != 0)
                        {
                            SegmentManager segmentManager = new SegmentManager();
                            ISegment       result         = segmentManager.GenerateAndMixSegments(callback);
                            if (result != null)
                            {
                                callback = (MethodCallbackInfo)result;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        if (serverBase.ClientServiceCallMethodsResult.TryGetValue(callback.Guid, out KeyValue <Type, object> resultTask))
                        {
                            if (callback.IsException)
                            {
                                resultTask.Value.GetType().FindMethod("SetException").Invoke(resultTask.Value, new object[] { new Exception(callback.Data) });
                            }
                            else
                            {
                                resultTask.Value.GetType().FindMethod("SetResult").Invoke(resultTask.Value, new object[] { ServerSerializationHelper.Deserialize(callback.Data, resultTask.Key, serverBase) });
                            }
                        }
                    }
                    else if (dataType == DataType.GetServiceDetails)
                    {
                        byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(stream, compressMode, serverBase.ProviderSetting.MaximumReceiveDataBlock);

                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = DecryptBytes(bytes, client);
                        string json    = Encoding.UTF8.GetString(bytes);
                        string hostUrl = ServerSerializationHelper.Deserialize <string>(json, serverBase);
                        ServerServicesManager serverServicesManager = new ServerServicesManager();
                        ProviderDetailsInfo   detail = serverServicesManager.SendServiceDetail(hostUrl, serverBase);
                        json = ServerSerializationHelper.SerializeObject(detail, serverBase);
                        List <byte> resultBytes = new List <byte>
                        {
                            (byte)DataType.GetServiceDetails,
                            (byte)CompressMode.None
                        };
                        byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
                        byte[] dataLen   = BitConverter.GetBytes(jsonBytes.Length);
                        resultBytes.AddRange(dataLen);
                        resultBytes.AddRange(jsonBytes);
                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, resultBytes.ToArray());
                    }
                    else if (dataType == DataType.GetMethodParameterDetails)
                    {
                        byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(stream, compressMode, serverBase.ProviderSetting.MaximumReceiveDataBlock);

                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = DecryptBytes(bytes, client);
                        string json = Encoding.UTF8.GetString(bytes);
                        MethodParameterDetails detail = ServerSerializationHelper.Deserialize <MethodParameterDetails>(json, serverBase);

                        if (!serverBase.RegisteredServiceTypes.TryGetValue(detail.ServiceName, out Type serviceType))
                        {
                            throw new Exception($"{client.IPAddress} {client.ClientId} Service {detail.ServiceName} not found");
                        }
                        if (serviceType == null)
                        {
                            throw new Exception($"{client.IPAddress} {client.ClientId} serviceType {detail.ServiceName} not found");
                        }

                        ServerServicesManager serverServicesManager = new ServerServicesManager();

                        json = serverServicesManager.SendMethodParameterDetail(serviceType, detail, serverBase);
                        List <byte> resultBytes = new List <byte>
                        {
                            (byte)DataType.GetMethodParameterDetails,
                            (byte)CompressMode.None
                        };

                        byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
                        byte[] dataLen   = BitConverter.GetBytes(jsonBytes.Length);
                        resultBytes.AddRange(dataLen);
                        resultBytes.AddRange(jsonBytes);
                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, resultBytes.ToArray());
                    }
                    else if (dataType == DataType.GetClientId)
                    {
                        byte[]      bytes  = Encoding.UTF8.GetBytes(client.ClientId);
                        List <byte> result = new List <byte>();
                        result.Add((byte)DataType.GetClientId);
                        result.Add((byte)CompressMode.None);

                        result.AddRange(BitConverter.GetBytes(bytes.Length));
                        result.AddRange(bytes);
                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = EncryptBytes(bytes, client);
                        if (result.Count > serverBase.ProviderSetting.MaximumSendDataBlock)
                        {
                            throw new Exception($"{client.IPAddress} {client.ClientId} GetClientId data length exceeds MaximumSendDataBlock");
                        }

                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, result.ToArray());
                    }
                    else
                    {
                        //throw new Exception($"Correct DataType Data {dataType}");
                        serverBase.AutoLogger.LogText($"Correct DataType Data {oneByteOfDataType} {client.ClientId} {client.IPAddress}");
                        break;
                    }
                }
                serverBase.DisposeClient(client, null, "StartToReadingClientData while break");
            }
            catch (Exception ex)
            {
                serverBase.AutoLogger.LogError(ex, $"{client.IPAddress} {client.ClientId} ServerBase SignalGoDuplexServiceProvider StartToReadingClientData");
                serverBase.DisposeClient(client, null, "SignalGoDuplexServiceProvider StartToReadingClientData exception");
            }
        }
        /// <summary>
        /// this method calll when client want to download file or stream from your server
        /// </summary>
        /// <param name="stream">client stream</param>
        /// <param name="client">client</param>
        private static async Task UploadStreamToClient(ClientInfo client, ServerBase serverBase)
        {
            MethodCallbackInfo callback   = null;
            IStreamInfo        streamInfo = null;
            PipeNetworkStream  userStream = null;
            PipeNetworkStream  stream     = client.ClientStream;
            bool isCallbackSended         = false;

            try
            {
                byte[] bytes = await client.StreamHelper.ReadBlockToEndAsync(client.ClientStream, CompressMode.None, serverBase.ProviderSetting.MaximumReceiveStreamHeaderBlock);

                string         json     = Encoding.UTF8.GetString(bytes);
                MethodCallInfo callInfo = ServerSerializationHelper.Deserialize <MethodCallInfo>(json, serverBase);
                CallMethodResultInfo <OperationContext> result = await CallMethod(callInfo.ServiceName, callInfo.Guid, callInfo.MethodName,
                                                                                  callInfo.Parameters, null, client, null, serverBase, null, null);

                callback   = result.CallbackInfo;
                streamInfo = result.StreamInfo;
                userStream = streamInfo.Stream;
                long len = streamInfo.Length.GetValueOrDefault();
                await SendCallbackData(callback, client, serverBase);

                isCallbackSended = true;
                long writeLen = 0;
                while (writeLen < len)
                {
                    bytes = new byte[1024 * 100];
                    int readCount = await userStream.ReadAsync(bytes, bytes.Length);

                    byte[] sendBytes = bytes.Take(readCount).ToArray();
                    await stream.WriteAsync(sendBytes, 0, sendBytes.Length);

                    writeLen += readCount;
                }
                userStream.Dispose();
                Console.WriteLine("user stream finished");
                stream.Dispose();
            }
            catch (Exception ex)
            {
                if (streamInfo != null)
                {
                    streamInfo.Dispose();
                }
                stream.Dispose();
                if (userStream != null)
                {
                    userStream.Dispose();
                    Console.WriteLine("user stream disposed");
                }
                if (!isCallbackSended && !client.ClientStream.IsClosed)
                {
                    if (callback == null)
                    {
                        callback = new MethodCallbackInfo();
                    }
                    callback.IsException = true;
                    callback.Data        = ServerSerializationHelper.SerializeObject(ex);
                    await SendCallbackData(callback, client, serverBase);
                }
            }
            finally
            {
                //MethodsCallHandler.EndStreamCallAction?.Invoke(client, guid, serviceName, methodName, values, jsonResult, exception);
            }
        }