/// <inheritdoc /> protected override void HandleClient(TcpClient tcpClient, NetworkStream networkStream) { Encoding enc = Encoding.UTF8; byte[] msg; int bytes = 0; Stopwatch stopwatch = new Stopwatch(); while (Running) { msg = new byte[RequestMaxPacketSize]; try { if (stopwatch.IsRunning) { stopwatch.Reset(); } bytes = networkStream.Read(msg, 0, RequestMaxPacketSize); stopwatch.Start(); } catch (ThreadAbortException) { throw; } catch (Exception e) { if (Running) { if (e.InnerException != null && e.InnerException is SocketException) { if (((SocketException)e.InnerException).SocketErrorCode == SocketError.TimedOut) { try { string remoteEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); tcpClient.Client.Shutdown(SocketShutdown.Both); tcpClient.Close(); Logger.LogTrace($"The connection to {remoteEndPoint} has been closed ordinarily after the timeout has been reached.", stopwatch); } catch { }; break; } else { string remoteEndPoint = "<unknown remote endpoint>"; try { remoteEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); tcpClient.Client.Shutdown(SocketShutdown.Both); tcpClient.Close(); Logger.LogTrace($"The connection to {remoteEndPoint} has been closed ordinarily after a SocketException occured. ({((SocketException)e.InnerException).SocketErrorCode})", stopwatch); break; } catch { } Logger.LogTrace($"A SocketException occured with {remoteEndPoint}. ({((SocketException)e.InnerException).SocketErrorCode})", stopwatch); break; } } Logger.LogError("An exception occured in the WebService client handler: " + e.SafeToString(), stopwatch); try { tcpClient.Client.Shutdown(SocketShutdown.Both); tcpClient.Close(); Logger.LogTrace($"The connection to {tcpClient.Client.RemoteEndPoint} has been closed ordinarily.", stopwatch); } catch { }; } break; } if (bytes == 0) { break; } try { WebServiceRequest request = Serializer.ReadJsonDataInMemory <WebServiceRequest>(enc.GetString(msg, 0, bytes)); request.IsRemoteRequest = true; WebServiceResponse response = null; try { response = RequestHandler.Request(request); } catch (Exception e) { response = WebServiceResponse.Exception(e); } byte[] buffer = enc.GetBytes(Serializer.WriteJsonDataInMemory(response)); networkStream.Write(buffer, 0, buffer.Length); } catch (ThreadAbortException) { throw; } catch (Exception e) { Logger.LogError("Error in WebServiceServer Client Handler: " + e.SafeToString(), stopwatch); } } }
/// <summary> /// Requests a certain WebServiceRequest at the local WebServiceHandler. /// </summary> /// <param name="webServiceRequest">The WebServiceRequest to reply to.</param> /// <returns>Returns the response as WebServiceResponse.</returns> public WebServiceResponse Request(WebServiceRequest webServiceRequest) { string typename = webServiceRequest.Namespace + "." + webServiceRequest.Type; IPEndPoint endPoint = UrlToServerHashMap[typename]; if (!webServiceRequest.WebServiceHandler) { webServiceRequest.WebServiceHandler = this; } if (webServiceRequest.IsRemoteRequest && endPoint != null) { return(WebServiceResponse.Exception(new ServiceNotAvailableException($"The requested Type '{typename}' is not locally available on this {nameof(WebServiceHandler)}, but was requested from a remote {nameof(WebServiceRequest)}."))); } if (endPoint == null) { Logger.LogWarning($"The type '{typename}' has not been added to the WebServiceHandler yet and therefore could not be resolved. Trying to generate local equivalent."); try { Type type = null; var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { type = assembly.GetType(typename); if (type != null) { Logger.LogInformation($"Auto generating Local WebService Implementation of Type '{typename}' from Assembly '{assembly.GetName()}'."); break; } } if (type == null) { throw new IncompatibleTypeException($"Type '{typename}' could not be found in the current {nameof(AppDomain)}."); } object ws = GetLocalService(type); var method = ws.GetType().GetMethod(webServiceRequest.Method, webServiceRequest._parameterTypes); try { if (method.ReturnType == typeof(WebServiceResponse)) { return((WebServiceResponse)method.Invoke(ws, webServiceRequest.Parameters)); } else { throw new IncompatibleTypeException($"Return type of method '{typename}.{method.Name}' was not '{nameof(WebServiceResponse)}'."); } } catch (WebServiceException) { throw; } catch (Exception e) { throw new RemoteException($"Failed to execute method '{webServiceRequest.Namespace}.{webServiceRequest.Type}.{webServiceRequest.Method}'.", e); } } catch (WebServiceException) { throw; } catch (Exception e) { throw new IncompatibleTypeException($"Type '{webServiceRequest.Namespace}.{webServiceRequest.Type}' could not be created.", e); } } else // Request from Remote WebServiceServer. { try { return(WebServiceServerRequest.Request(webServiceRequest, endPoint)); } catch (Exception e) { throw new ServiceNotAvailableException($"Exception in requesting from a remote WebServiceServer at '{endPoint}'.", e); } } }