Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
0
        /// <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);
                }
            }
        }