Ping WCF/Web Service

22. September 2015

Wie stellt man im Code fest ob ein WCF/Web Service überhaupt erreichbar ist?

Untitled

Wenn man die Möglichkeit hat, die Hostseite um eine Methode void Ping() oder dynamisch zu erweitern, ist dies relativ einfach. Doch meist hat man über den Host keine Kontrolle. Im Folgenden möchte ich für die Protokolle nettcp und http/https aufzeigen, wie man herausfindet ob der entsprechende Service erreichbar ist, ohne eine Methode (OperationContract) aufzurufen. Leider ist dies immer protokollabhängig

ping nettcp

Beim Protokoll nettcp ist dies relativ einfach, denn die Verbindung wird wirklich beim Open() aufgebaut und geprüft. Entweder nutzt man dafür den generierten Proxy (ClientBase<T>) oder die ChannelFactory<T> direkt, denn beide sind von ICommunicationObject vererbt.

private bool Open(ICommunicationObject  channel)

{

    try

    {

        // Verbindung aufbauen

        channel.Open();

        channel.Close();

        

        return true;

    }

    catch(Exception ex)

    {

        //log ex

        return false;

    }

}

ping http/https

Open() reicht hier nicht aus, denn die Verbindung wird nur kurz für den Request und Response geöffnet. Somit muss man den Server wirklich anfragen. Am besten wäre dies wohl über die Erweiterung des ServiceContracts (siehe oben: void Ping() oder dynamisch zu realisieren. Ohne Einfluss auf die Implementierung des Hostes ist man jedoch auf andere Mittel und Wege angewiesen. Bei HTTP bieten sich dafür die HTTP-Methods an. Wobei nachteilig nicht jeder Service diesen Standard vollumfänglich bereitstellt. Aus diesem Grund durchlaufe ich mehre Request, beginnend mit den gängigsten HTTP-Methods. Sobald einer erfolgreich war, ist der Service erreichbar. Durch ein detaillierteres Fehlerhandling wäre es ebenfalls denkbar den Status des Services abzuleiten. Beispielsweise würde ein “Access Denied” bedeuten, dass der Service online ist.

using System.Net;

 

private bool SendHttpWebRequest(Uri uri)

{

    if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)

        return false;

 

    foreach (string method in new string[] { "GET", "OPTIONS", "HEAD", "TRACE", "CONNECT" })

    {

        try

        {

            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.CreateDefault(uri);

 

            httpRequest.UseDefaultCredentials = true;

            httpRequest.Method = method;

 

            using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())

            {

                if (httpResponse.StatusCode == HttpStatusCode.OK)

                    return true;

            }

        }

        catch

        {

            //alles wegfangen

        }

    }

 

    return false;

}