LJPResponse ReceiveResponse(ICollection <Type> tpeNamespace, bool bThrowExceptionWithNotData = true) { //Receive Header Array.Clear(receiveBuffer, 0, receiveBuffer.Length); ClientConnector.Receive(receiveBuffer, 0, receiveBuffer.Length); return(ConvertToLJPResponse(tpeNamespace, receiveBuffer, bThrowExceptionWithNotData)); }
private LJPResponse ConvertToLJPResponse( ICollection <Type> tpeNamespace , byte[] aReceiveBuffer , bool bThrowExceptionWithNotData) { byte[] dinamycBufferToAllMessage = null; try { LJPResponse oLJPResponse = new LJPResponse(); var indexOfHeaderAndBodySeparator = ByteHelper.IndexOf(aReceiveBuffer , 0 , new byte[] { Convert.ToByte('\n'), Convert.ToByte('\n') }); if (indexOfHeaderAndBodySeparator == -1) { throw new LJPException("Bad Little Json Protocol, Expected Response Object") { LJPExceptionType = LJPExceptionType.BadProtocol }; } #region Extracting Header Of SendResponse Message var headerBytes = new byte[indexOfHeaderAndBodySeparator]; Array.Copy(aReceiveBuffer, headerBytes, indexOfHeaderAndBodySeparator); string headerUTF8 = Encoding.UTF8.GetString(headerBytes); var headerUTF8Splited = headerUTF8.Split('\n'); if (headerUTF8Splited.Length < 2 || indexOfHeaderAndBodySeparator == -1) { throw new LJPException("Bad Little Json Protocol, Expected Response Object") { LJPExceptionType = LJPExceptionType.BadProtocol }; } #if DEBUG logger.Debug($"Header=[{string.Join(", ", headerUTF8Splited) }]"); #endif //Receive Total of json object var lengthAndValueInString = headerUTF8Splited.Single(o => o.Contains("Length=")); var typeAndValueInString = headerUTF8Splited.Single(o => o.Contains("Type=")); #endregion var lengthInString = lengthAndValueInString.Split(new char[] { '=' }, 2)[1]; var typeInString = typeAndValueInString.Split(new char[] { '=' }, 2)[1]; oLJPResponse.iLength = int.Parse(lengthInString); try { Type tpePrimitive = TryToResolvePrimitivesType(typeInString); if (nameof(LJPExceptionDTO).Equals(typeInString, StringComparison.OrdinalIgnoreCase)) { oLJPResponse.tpeObject = reflector.GetType(typeof(LJPExceptionDTO), typeInString); } else if (tpePrimitive == null) { Type tpetryGetType = null; foreach (var tpeNamespaceFE in tpeNamespace) { if (reflector.TryGetType(tpeNamespaceFE, typeInString, out tpetryGetType)) { oLJPResponse.tpeObject = tpetryGetType; break; } } if (oLJPResponse.tpeObject == null) { throw new ArgumentException($"Type not found in namespaces:\n\"{string.Join(",", tpeNamespace)}\""); } } else { oLJPResponse.tpeObject = tpePrimitive; } } catch (Exception ex) { logger.Error(ex.ToString()); throw new LJPException($"Error: trying to get type \"{typeInString}\" in namespace \"{tpeNamespace}\"."); } //Receive the json object part int indexOfEndOfBody = ByteHelper.IndexOf(aReceiveBuffer, indexOfHeaderAndBodySeparator + 2, new byte[] { Convert.ToByte('\0') }); indexOfEndOfBody = indexOfEndOfBody == -1 ? aReceiveBuffer.Length : indexOfEndOfBody; var firstExtractOfBody = new byte[indexOfEndOfBody - (indexOfHeaderAndBodySeparator + 2)]; if (firstExtractOfBody.Length > oLJPResponse.iLength) { throw new LJPException($"Bad body length Had={firstExtractOfBody.Length}, Expected={oLJPResponse.iLength}."); } Buffer.BlockCopy(aReceiveBuffer, indexOfHeaderAndBodySeparator + 2, firstExtractOfBody, 0, firstExtractOfBody.Length); int receivedToNow = firstExtractOfBody.Length; dinamycBufferToAllMessage = new byte[oLJPResponse.iLength]; Buffer.BlockCopy(firstExtractOfBody, 0, dinamycBufferToAllMessage, 0, receivedToNow); //Whether there is more fragment of the object string receivedMessageInASCII = ""; while (receivedToNow < oLJPResponse.iLength) { Array.Clear(aReceiveBuffer, 0, aReceiveBuffer.Length); ClientConnector.Receive(aReceiveBuffer, 0, aReceiveBuffer.Length); int indexOfEnd = ByteHelper.IndexOf(aReceiveBuffer, 0, nullByteInArray); indexOfEnd = indexOfEnd == -1 ? aReceiveBuffer.Length : indexOfEnd; indexOfEnd = Math.Min(oLJPResponse.iLength - receivedToNow, indexOfEnd); Buffer.BlockCopy(aReceiveBuffer, 0, dinamycBufferToAllMessage, receivedToNow, indexOfEnd); receivedToNow += indexOfEnd; logger.Debug($"[ReceivePart={receivedMessageInASCII.Length}] [{receivedToNow}/{oLJPResponse.iLength}]"); if (indexOfEnd == 0 || indexOfEnd == -1) { break; } } var sObject = Encoding.UTF8.GetString(dinamycBufferToAllMessage); #if DEBUG logger.Debug($"Received Message: [{sObject.Replace("\n", "[nl]")}]"); #endif dynamic oObject = null; //using (MemoryStream oMS = new()) //{ //using StreamWriter oSW = new(oMS); //DataContractJsonSerializer oJsonSerializer = new(oLJPResponse.tpeObject); //oSW.Write(sObject); //oSW.Flush(); //oMS.Position = 0; //oObject = oJsonSerializer.ReadObject(oMS); //oLJPResponse.oObject = oObject; //} oObject = JsonConvert.DeserializeObject(sObject, oLJPResponse.tpeObject); oLJPResponse.oObject = oObject; if (oObject is LJPExceptionDTO && bThrowExceptionWithNotData) { var oLJPException = oObject as LJPExceptionDTO; var nLJPEExceptionType = (LJPExceptionType)oLJPException.IClientLJPExceptionType; var exception = new LJPException(oLJPException.Message, nLJPEExceptionType, oLJPException.Code) { SerializedData = oLJPException.SerializedData }; throw exception; } else if (oObject is LJPExceptionDTO && !bThrowExceptionWithNotData) { oLJPResponse.oObject = null; } return(oLJPResponse); } finally { dinamycBufferToAllMessage = null; } }
public LJPCallReceived ReceiveCall(params string[] servicesLayers) { byte[] dinamycBufferToAllMessage = null; try { LJPCallReceived oLJPCallResponse = new LJPCallReceived(); //Receive Header Array.Clear(receiveBuffer, 0, receiveBuffer.Length); ClientConnector.Receive(receiveBuffer, 0, receiveBuffer.Length); var indexOfHeaderAndBodySeparator = ByteHelper.IndexOf(receiveBuffer , 0 , new byte[] { Convert.ToByte('\n'), Convert.ToByte('\n') }); if (indexOfHeaderAndBodySeparator == -1) { throw new LJPException("Bad little json protocol, header body separator not found.") { LJPExceptionType = LJPExceptionType.BadProtocol }; } #region Parsing Raw Data Header Of SendCall Message var headerBytes = new byte[indexOfHeaderAndBodySeparator]; Array.Copy(receiveBuffer, headerBytes, indexOfHeaderAndBodySeparator); string headerUTF8 = Encoding.UTF8.GetString(headerBytes); var headerUTF8Splited = headerUTF8.Split('\n'); //string message = Encoding.UTF8.GetString(this.aReceiveBuffer); #if DEBUG logger.Debug($"Header=[{string.Join(", ", headerUTF8Splited) }]"); #endif var lengthLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Length=")); var commandIdLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Id=")); var stayAliveLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("KeepAlive=")); var needResponseLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("NeedResponse=")); var interfaceLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Interface=")); var methodLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Method=")); var versionLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Version=")); var typeLine = headerUTF8Splited.SingleOrDefault(o => o.Contains("Type=")); if (versionLine == null) { versionLine = "Version=0.0"; } //If is a exception if (typeLine != null && typeLine.Split(new char[] { '=' }, 2)[1] == nameof(LJPExceptionDTO)) { ConvertToLJPResponse(new List <Type>() { typeof(LJPExceptionDTO) }, receiveBuffer, true); } if (lengthLine == null || commandIdLine == null || stayAliveLine == null || needResponseLine == null || interfaceLine == null || methodLine == null) { throw new LJPException("Bad little json protocol header, all or some fields nulls.") { LJPExceptionType = LJPExceptionType.BadProtocol }; } var rawLength = lengthLine.Split(new char[] { '=' }, 2)[1]; var rawCommandId = commandIdLine.Split(new char[] { '=' }, 2)[1]; var rawStayAlive = stayAliveLine.Split(new char[] { '=' }, 2)[1]; var rawNeedResponse = needResponseLine.Split(new char[] { '=' }, 2)[1]; var rawInterface = interfaceLine.Split(new char[] { '=' }, 2)[1]; var rawMethod = methodLine.Split(new char[] { '=' }, 2)[1]; var rawVersion = versionLine.Split(new char[] { '=' }, 2)[1]; #endregion #region Converting header types to layer types if (!long.TryParse(rawCommandId, out long commandId)) { oLJPCallResponse.Id = null; } else { oLJPCallResponse.Id = commandId; } oLJPCallResponse.iLength = int.Parse(rawLength); oLJPCallResponse.KeepAlive = bool.Parse(rawStayAlive); oLJPCallResponse.NeedResponse = bool.Parse(rawNeedResponse); oLJPCallResponse.Version = rawVersion; KeepAlive = oLJPCallResponse.KeepAlive; Type serviceInterface = null; Assembly ass = null; foreach (var serviceLayer in servicesLayers) { if (Path.GetExtension(serviceLayer) == ".dll") { //ass = Assembly.LoadFrom(serviceLayer); throw new NotImplementedException(); } else { ass = Assembly.Load(new AssemblyName(serviceLayer)); } serviceInterface = ass.GetTypes().SingleOrDefault(o => o.Name.Equals(rawInterface, StringComparison.OrdinalIgnoreCase)); if (serviceInterface != null) { var methodOfInterface = serviceInterface.GetTypeInfo().GetMethod(rawMethod); if (methodOfInterface != null) { oLJPCallResponse.Method = methodOfInterface; break; } } } oLJPCallResponse.Interface = serviceInterface ?? throw new LJPException($"Bad little json protocol, Interface or method not found in layers:\n\t{string.Join("\n\t", serviceInterface)}", LJPExceptionType.FormatException); #endregion #region Receiving the json object string part int indexOfEndOfBody = ByteHelper.IndexOf(receiveBuffer, indexOfHeaderAndBodySeparator + 2, new byte[] { Convert.ToByte('\0') }); indexOfEndOfBody = indexOfEndOfBody == -1 ? receiveBuffer.Length : indexOfEndOfBody; var firstExtractOfBody = new byte[indexOfEndOfBody - (indexOfHeaderAndBodySeparator + 2)]; if (firstExtractOfBody.Length > oLJPCallResponse.iLength) { throw new LJPException($"Bad body length Had={firstExtractOfBody.Length}, Expected={oLJPCallResponse.iLength}."); } Buffer.BlockCopy(receiveBuffer, indexOfHeaderAndBodySeparator + 2, firstExtractOfBody, 0, firstExtractOfBody.Length); int receivedToNow = firstExtractOfBody.Length; dinamycBufferToAllMessage = new byte[oLJPCallResponse.iLength]; Buffer.BlockCopy(firstExtractOfBody, 0, dinamycBufferToAllMessage, 0, receivedToNow); //Whether there is more fragment of the object while (receivedToNow < oLJPCallResponse.iLength) { Array.Clear(receiveBuffer, 0, receiveBuffer.Length); ClientConnector.Receive(receiveBuffer, 0, receiveBuffer.Length); int indexOfEnd = ByteHelper.IndexOf(receiveBuffer, 0, nullByteInArray); indexOfEnd = indexOfEnd == -1 ? receiveBuffer.Length : indexOfEnd; Buffer.BlockCopy(receiveBuffer, 0, dinamycBufferToAllMessage, receivedToNow, indexOfEnd); receivedToNow += indexOfEnd; if (indexOfEnd == 0 || indexOfEnd == -1) { break; } } var sObject = Encoding.UTF8.GetString(dinamycBufferToAllMessage); #endregion //Converting message var messageExtractor = factoryClientLJP.CreateMessageFactory(oLJPCallResponse.Version); messageExtractor.Parse(oLJPCallResponse, sObject); return(oLJPCallResponse); } catch (SerializationException se) { throw new LJPException($"Bad protocol, problem when deserialize, detail: {se.Message}", LJPExceptionType.BadProtocol); } }