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--; } }
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); }
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 }
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); } }
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); }
//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); }
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); } }