コード例 #1
0
        public KeyValue <DataType, CompressMode> ReadFirstData(PipeNetworkStream stream, int maximumReceiveStreamHeaderBlock)
        {
            DataType     responseType = (DataType)SignalGoStreamBase.CurrentBase.ReadOneByte(stream);
            CompressMode compressMode = (CompressMode)SignalGoStreamBase.CurrentBase.ReadOneByte(stream);

            return(new KeyValue <DataType, CompressMode>(responseType, compressMode));
        }
コード例 #2
0
        public static async void StartToReadingClientData(ClientInfo client, ServerBase serverBase)
        {
            try
            {
                Console.WriteLine($"Stream Client Connected: {client.IPAddress}");
                PipeNetworkStream stream = client.ClientStream;
                byte firstByte           = await client.StreamHelper.ReadOneByteAsync(stream);

                if (firstByte == 0)
                {
                    await DownloadStreamFromClient(client, serverBase);
                }
                //download from server and upload from client
                else
                {
                    await UploadStreamToClient(client, serverBase);
                }
                serverBase.DisposeClient(client, null, "StartToReadingClientData finished");
            }
            catch (Exception ex)
            {
                serverBase.AutoLogger.LogError(ex, $"{client.IPAddress} {client.ClientId} ServerBase SignalGoStreamProvider StartToReadingClientData");
                serverBase.DisposeClient(client, null, "SignalGoStreamProvider StartToReadingClientData exception");
            }
        }
コード例 #3
0
        /// <summary>
        /// initialzie and read client
        /// </summary>
        /// <param name="tcpClient"></param>
        public void InitializeClient(TcpClient tcpClient)
        {
            Task.Run(async() =>
            {
                try
                {
                    tcpClient.GetStream().ReadTimeout  = 5000;
                    tcpClient.GetStream().WriteTimeout = 5000;
                    PipeNetworkStream stream           = new PipeNetworkStream(new NormalStream(await tcpClient.GetTcpStream(_serverBase)), (int)_serverBase.ProviderSetting.ReceiveDataTimeout.TotalMilliseconds);
                    ExchangeClient(stream, tcpClient);
                }
                catch (Exception)
                {
#if (NETSTANDARD)
                    tcpClient.Dispose();
#else
                    tcpClient.Close();
#endif
                }
            });
        }
コード例 #4
0
        /// <summary>
        /// create client information
        /// </summary>
        /// <param name="isHttp"></param>
        /// <param name="tcpClient"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public ClientInfo CreateClientInfo(bool isHttp, TcpClient tcpClient, PipeNetworkStream stream)
        {
            ClientInfo client = null;

            if (isHttp)
            {
                client = new HttpClientInfo(_serverBase);
            }
            else
            {
                client = new ClientInfo(_serverBase);
            }
            client.ConnectedDateTime = DateTime.Now;
            client.TcpClient         = tcpClient;
            //client.IPAddressBytes = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString().Replace("::ffff:", "");
            client.IPAddressBytes = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.GetAddressBytes();
            client.ClientId       = Guid.NewGuid().ToString();
            _serverBase.Clients.TryAdd(client.ClientId, client);
            client.ClientStream = stream;
            _serverBase.OnClientConnectedAction?.Invoke(client);
            return(client);
        }
コード例 #5
0
        public async Task <HttpClientResponseBase> PostHeadAsync(string url, ParameterInfo[] parameterInfoes, BaseStreamInfo streamInfo = null)
        {
            string    newLine   = TextHelper.NewLine;
            Uri       uri       = new Uri(url);
            TcpClient tcpClient = new TcpClient(uri.Host, uri.Port);

            try
            {
                if (streamInfo != null && (!streamInfo.Length.HasValue || streamInfo.Length <= 0))
                {
                    throw new Exception("Please set streamInfo.Length before upload your stream!");
                }
                string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
                string headData = $"POST {uri.AbsolutePath} HTTP/1.1" + newLine + $"Host: {uri.Host}" + newLine + $"Content-Type: multipart/form-data; boundary={boundary}" + newLine;
                if (RequestHeaders != null && RequestHeaders.Count > 0)
                {
                    foreach (KeyValuePair <string, string[]> item in RequestHeaders)
                    {
                        if (!item.Key.Equals("host", StringComparison.OrdinalIgnoreCase) && !item.Key.Equals("content-type", StringComparison.OrdinalIgnoreCase) && !item.Key.Equals("content-length", StringComparison.OrdinalIgnoreCase))
                        {
                            if (item.Value == null || item.Value.Length == 0)
                            {
                                continue;
                            }
                            headData += item.Key + ": " + string.Join(",", item.Value) + newLine;
                        }
                    }
                }
                StringBuilder valueData = new StringBuilder();
                if (parameterInfoes != null)
                {
                    string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                    string boundaryinsert   = TextHelper.NewLine + "--" + boundary + TextHelper.NewLine;
                    foreach (ParameterInfo item in parameterInfoes)
                    {
                        valueData.AppendLine(boundaryinsert);
                        valueData.Append(string.Format(formdataTemplate, item.Name, item.Value));
                    }
                }

                byte[] dataBytes = Encoding.GetBytes(valueData.ToString());
                headData += $"Content-Length: {dataBytes.Length}" + newLine + newLine;

                byte[] headBytes = Encoding.GetBytes(headData);

                Stream stream = uri.Port == 443 ? (Stream) new SslStream(tcpClient.GetStream()) : tcpClient.GetStream();

                if (uri.Port == 443)
                {
                    SslStream sslStream = (SslStream)stream;
                    await sslStream.AuthenticateAsClientAsync(uri.Host);
                }
                stream.Write(headBytes, 0, headBytes.Length);
                stream.Write(dataBytes, 0, dataBytes.Length);

                if (streamInfo != null)
                {
                    int sentBytesCount = 0;
                    int wantReadCount  = 1024 * 512;
                    while (streamInfo.Length > sentBytesCount)
                    {
                        if (wantReadCount > streamInfo.Length - sentBytesCount)
                        {
                            wantReadCount = (int)(streamInfo.Length - sentBytesCount);
                        }
                        byte[] result    = new byte[wantReadCount];
                        int    readCount = await streamInfo.Stream.ReadAsync(result, wantReadCount);

                        await stream.WriteAsync(result, 0, readCount);

                        sentBytesCount += readCount;
                    }
                }

                PipeNetworkStream pipelineReader = new PipeNetworkStream(new NormalStream(stream), 30000);

                List <string> lines = new List <string>();
                string        line  = null;
                do
                {
                    if (line != null)
                    {
                        lines.Add(line.TrimEnd());
                    }
                    line = await pipelineReader.ReadLineAsync();
                }while (line != newLine);
                HttpClientResponseBase httpClientResponse = new HttpClientResponseBase
                {
                    Status          = (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), lines[0].Split(' ')[1]),
                    ResponseHeaders = SignalGo.Shared.Http.WebHeaderCollection.GetHttpHeaders(lines.Skip(1).ToArray()),
                    Stream          = pipelineReader,
                    TcpClient       = tcpClient
                };
                Response = httpClientResponse;
                return(httpClientResponse);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
コード例 #6
0
        /// <summary>
        /// Exchange data from client and server
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="tcpClient"></param>
        public async void ExchangeClient(PipeNetworkStream reader, TcpClient tcpClient)
        {
            //File.WriteAllBytes("I:\\signalgotext.txt", reader.LastBytesReaded);
            ClientInfo client = null;

            try
            {
                if (_serverBase.ProviderSetting.IsEnabledToUseTimeout)
                {
                    tcpClient.GetStream().ReadTimeout  = (int)_serverBase.ProviderSetting.ReceiveDataTimeout.TotalMilliseconds;
                    tcpClient.GetStream().WriteTimeout = (int)_serverBase.ProviderSetting.SendDataTimeout.TotalMilliseconds;
                }

                string firstLineString = await reader.ReadLineAsync();

                if (firstLineString.Contains("SignalGo-Stream/4.0"))
                {
                    if (!_serverBase.ProviderSetting.IsEnabledToUseTimeout)
                    {
                        tcpClient.GetStream().ReadTimeout  = -1;
                        tcpClient.GetStream().WriteTimeout = -1;
                    }
                    client = CreateClientInfo(false, tcpClient, reader);
                    client.ProtocolType = ClientProtocolType.SignalGoStream;
                    client.StreamHelper = SignalGoStreamBase.CurrentBase;
                    SignalGoStreamProvider.StartToReadingClientData(client, _serverBase);
                }
                else if (firstLineString.Contains("SignalGo-OneWay/4.0"))
                {
                    if (!_serverBase.ProviderSetting.IsEnabledToUseTimeout)
                    {
                        tcpClient.GetStream().ReadTimeout  = -1;
                        tcpClient.GetStream().WriteTimeout = -1;
                    }
                    client = CreateClientInfo(false, tcpClient, reader);
                    client.ProtocolType = ClientProtocolType.SignalGoOneWay;
                    client.StreamHelper = SignalGoStreamBase.CurrentBase;
                    OneWayServiceProvider.StartToReadingClientData(client, _serverBase);
                }
                else if (firstLineString.Contains("SignalGo/4.0"))
                {
                    client = CreateClientInfo(false, tcpClient, reader);
                    client.ProtocolType = ClientProtocolType.SignalGoDuplex;
                    //"SignalGo/1.0";
                    client.StreamHelper = SignalGoStreamBase.CurrentBase;
                    if (_serverBase.ProviderSetting.ServerServiceSetting.IsEnabledToUseTimeout)
                    {
                        tcpClient.ReceiveTimeout = (int)_serverBase.ProviderSetting.ServerServiceSetting.ReceiveDataTimeout.TotalMilliseconds;
                        tcpClient.SendTimeout    = (int)_serverBase.ProviderSetting.ServerServiceSetting.SendDataTimeout.TotalMilliseconds;
                    }
                    else
                    {
                        tcpClient.GetStream().ReadTimeout  = -1;
                        tcpClient.GetStream().WriteTimeout = -1;
                    }
                    await SignalGoDuplexServiceProvider.StartToReadingClientData(client, _serverBase);
                }
                else if (firstLineString.Contains("HTTP/"))
                {
                    if (_serverBase.ProviderSetting.HttpSetting.IsEnabledToUseTimeout)
                    {
                        tcpClient.GetStream().ReadTimeout  = (int)_serverBase.ProviderSetting.HttpSetting.ReceiveDataTimeout.TotalMilliseconds;
                        tcpClient.GetStream().WriteTimeout = (int)_serverBase.ProviderSetting.HttpSetting.SendDataTimeout.TotalMilliseconds;
                    }
                    await HttpProvider.StartToReadingClientData(tcpClient, _serverBase, reader, new StringBuilder(firstLineString));
                }
                else
                {
                    _serverBase.DisposeClient(client, tcpClient, "AddClient header not support");
                }
            }
            catch (Exception)
            {
                _serverBase.DisposeClient(client, tcpClient, "exception");
            }
            finally
            {
                _WaitingToReadFirstLineCount--;
            }
        }
コード例 #7
0
 public StreamInfo(PipeNetworkStream stream)
 {
     Stream = stream;
 }
コード例 #8
0
ファイル: StreamGo.cs プロジェクト: konkopp/SignalGo-full-net
 public StreamGo(PipeNetworkStream currentStream)
 {
     CurrentStream = currentStream;
 }
コード例 #9
0
        public static async Task StartToReadingClientData(ClientInfo client, ServerBase serverBase)
        {
            try
            {
                Console.WriteLine($"Duplex Client Connected: {client.IPAddress}");
                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)
                    {
                        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);
                        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;
                            }
                        }
                        Task <MethodCallbackInfo> callbackResult = CallMethod(callInfo, client, json, serverBase);
                        SendCallbackDataAsync(callbackResult, client, serverBase);
                    }

                    //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);
                        //if (ClientsSettings.ContainsKey(client))
                        //    bytes = EncryptBytes(bytes, client);
                        byte[]      len  = BitConverter.GetBytes(bytes.Length);
                        List <byte> data = new List <byte>
                        {
                            (byte)DataType.GetClientId,
                            (byte)CompressMode.None
                        };
                        data.AddRange(len);
                        data.AddRange(bytes);
                        if (data.Count > serverBase.ProviderSetting.MaximumSendDataBlock)
                        {
                            throw new Exception($"{client.IPAddress} {client.ClientId} GetClientId data length exceeds MaximumSendDataBlock");
                        }

                        await client.StreamHelper.WriteToStreamAsync(client.ClientStream, data.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");
            }
        }
コード例 #10
0
        public static async Task StartToReadingClientData(TcpClient tcpClient, ServerBase serverBase, PipeNetworkStream reader, StringBuilder builder)
        {
            //Console.WriteLine($"Http Client Connected: {((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString().Replace("::ffff:", "")}");
            ClientInfo client = null;

            try
            {
                while (true)
                {
                    string line = await reader.ReadLineAsync();

                    builder.Append(line);
                    if (line == TextHelper.NewLine)
                    {
                        break;
                    }
                }
                string requestHeaders = builder.ToString();

                if (requestHeaders.Contains("Sec-WebSocket-Key"))
                {
                    tcpClient.ReceiveTimeout = -1;
                    tcpClient.SendTimeout    = -1;
                    client = serverBase.ServerDataProvider.CreateClientInfo(false, tcpClient, reader);
                    client.ProtocolType = ClientProtocolType.WebSocket;
                    client.IsWebSocket  = true;
                    string key          = requestHeaders.Replace("ey:", "`").Split('`')[1].Replace("\r", "").Split('\n')[0].Trim();
                    string acceptKey    = AcceptKey(ref key);
                    string newLine      = TextHelper.NewLine;

                    //var response = "HTTP/1.1 101 Switching Protocols" + newLine
                    string response = "HTTP/1.0 101 Switching Protocols" + newLine
                                      + "Upgrade: websocket" + newLine
                                      + "Connection: Upgrade" + newLine
                                      + "Sec-WebSocket-Accept: " + acceptKey + newLine + newLine;
                    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(response);
                    await client.ClientStream.WriteAsync(bytes, 0, bytes.Length);

                    client.StreamHelper = SignalGoStreamBase.CurrentBase;
                    client.ClientStream = new PipeNetworkStream(new WebSocketStream(client.TcpClient.GetStream()));
                    if (requestHeaders.Contains("SignalgoDuplexWebSocket"))
                    {
                        await SignalGoDuplexServiceProvider.StartToReadingClientData(client, serverBase);
                    }
                    else
                    {
                        //client.StreamHelper = SignalGoStreamWebSocketLlight.CurrentWebSocket;
                        //client.ClientStream = new PipeNetworkStream(new WebSocketStream(client.TcpClient.GetStream()));
                        //await WebSocketProvider.StartToReadingClientData(client, serverBase);

                        await HttpProvider.AddWebSocketHttpClient(client, serverBase);
                    }
                }
                else if (requestHeaders.Contains("SignalGoHttpDuplex"))
                {
                    client = serverBase.ServerDataProvider.CreateClientInfo(false, tcpClient, reader);
                    client.ProtocolType = ClientProtocolType.HttpDuplex;
                    client.StreamHelper = SignalGoStreamBase.CurrentBase;
                    await SignalGoDuplexServiceProvider.StartToReadingClientData(client, serverBase);
                }
                else
                {
                    try
                    {
                        //serverBase.TaskOfClientInfoes
                        client = (HttpClientInfo)serverBase.ServerDataProvider.CreateClientInfo(true, tcpClient, reader);
                        client.ProtocolType = ClientProtocolType.Http;
                        client.StreamHelper = SignalGoStreamBase.CurrentBase;

                        string[] lines = null;
                        if (requestHeaders.Contains(TextHelper.NewLine + TextHelper.NewLine))
                        {
                            lines = requestHeaders.Substring(0, requestHeaders.IndexOf(TextHelper.NewLine + TextHelper.NewLine)).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                        }
                        else
                        {
                            lines = requestHeaders.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                        }
                        if (lines.Length > 0)
                        {
                            string methodName = GetHttpMethodName(lines[0]);
                            string address    = GetHttpAddress(lines[0]);
                            if (requestHeaders != null)
                            {
                                ((HttpClientInfo)client).RequestHeaders = SignalGo.Shared.Http.WebHeaderCollection.GetHttpHeaders(lines.Skip(1).ToArray());
                            }

                            await HandleHttpRequest(methodName, address, serverBase, (HttpClientInfo)client);
                        }
                        else
                        {
                            serverBase.DisposeClient(client, tcpClient, "HttpProvider StartToReadingClientData no line detected");
                        }
                    }
                    catch
                    {
                        serverBase.DisposeClient(client, tcpClient, "HttpProvider StartToReadingClientData exception");
                    }
                }
            }
            catch (Exception ex)
            {
                //if (client != null)
                //serverBase.AutoLogger.LogError(ex, $"{client.IPAddress} {client.ClientId} ServerBase HttpProvider StartToReadingClientData");
                serverBase.DisposeClient(client, tcpClient, "HttpProvider StartToReadingClientData exception 2");
            }
        }
コード例 #11
0
        /// <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);
            }
        }