bebugs Blog


Willkommen auf meiner Homepage. Wer Lust hat kann sich gern über Messenger oder im gulli irc melden.

ICQ: 164621172
MSN: nuqer@hotmail.de

GreenfieldGrafix
-Affi-
-Affi-
-Affi-
-Affi-
-Affi-
-Affi-
-Affi-
-Affi-
Wer eingetragen werden möchte meldet sich einfach

Wir haben bezahlt!


Buttonnetzwerk für ein freies Internet

Disclaimer
Abonieren

Artikel

Lockerz invites

Atomexplosion
Barbie jeeptuning
Batman 1966
Geiler Klingelton
Der große blaue Bär in da House
Die Elite des Internets 1
Die Elite des Internets 2
Die Elite des Internets 3
eBooks
Eigenes Layout designen
Fahrradfahrer
Farbkombinationen
Finanzkrisengewinner
Fontstruct
Gema Rohlinge
Head Tracking
Herzblatt Synchro
ICQ-Spam
Informiert Wolfgang
Lars the Emo Kid
Lockpicks herstellen
Magnetisches Armband
Matrix Flash
Nerdwebsites
Tilt-Shift-Effekt
Online TV Recorder
Orisinal
Out Drink Santa
Out of Bounds
Sandboxie
Shepard-Skala
Stickman Exodus
Super Mario World
Ultimate Defrag 1
Ultimate Defrag 2
USB-Stick Autorun
Von wegen Klimaschwindel
WCF Tutorial 1
WCF Tutorial 2"
---

Mein neuer Blog

 

Gratis bloggen bei
myblog.de

Gratis bloggen bei
myblog.de

Blogverzeichnis - Blog Verzeichnis bloggerei.de
WCF-Tutorial 1

Immer mehr Anwendungen sind vernetzt. Vor einigen Jahren waren Computerspiele mit Netzwerkunterstützung noch eine Seltenheit und heute kann man die meisten nicht einmal mehr Registrieren, wenn man kein Internet besitzt. Aber auch Cloudcomputing und andere Netzwerkanwendungen rücken immer stärker in den Vordergrund.

Natürlich möchte man in einer modernen Zeit auch eine moderne Lösungen für die steigende Anzahl der Netzwerkprogramme. Keiner möchte sich mehr mit Socketprogrammierung rumschlagen.
Microsoft hat mit Windows Communication Foundation (WCF), einem Bestandteil aus .Net, einen Weg in die Zukunft eingeschlagen. Netzwerkanwendungen zu programmieren ist dabei ohne große Schwierigkeiten möglich.

Es gibt zwar schon unzählige WCF-Tutorials im Internet die ziemlich gut sind, doch da ich selber noch lerne dachte ich mir, dass es das beste ist selber darüber zu schreiben.  So lernt man das glaub am besten. In meinem ersten Tutorial zeige ich nur grob wie WCF funktioniert und lasse einen Client mit einem Host kommunizieren. In meinem zweiten Tutorial gehe ich tiefer in die Möglichkeiten von WCF ein und erstelle einen kleinen Chatserver an dem sich mehrere Teilnehmer einloggen können.

 

Zu beginn des Tutorials solltet ihr euch eine Projektmappe mit 2 Projekten erstellen. Beide Projekte sollten dabei einfache C#-Consolenanwendungen sein. Als Verweise fügt ihr beiden Projekten System.ServiceModel hinzu. Ich habe meine Projekte WCF_Tut_Client und WCF_Tut_Host genannt.


Als erstes erstellen wir eine Klasse mit Funktionen, die der Host dem Client anbieten soll. Auf diese Funktionen kann der Client später wie auf normale Funktionen zugreifen. Eigentlich sollte man das alles als Interface aufsetzten, aber da ich es hier erst einmal einfach halten möchte schreibe ich das in eine normale Klasse. Fügt also dem Host eine Datei hinzu die HostFunctions heißt.

HostFunctions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCF_Tut_Host
{
    [ServiceContract()]
    class HostFunctions
    {
        [OperationContract]
        public string getDate()
        {
            return DateTime.Today.DayOfWeek.ToString();
        }

        [OperationContract]
        public string getTime()
        {
            return DateTime.Now.ToString();
        }
    }
}

 

Wichtig sind dabei die Attribute über der Klasse und den Funktionen. Diese definieren einen Dienstvertrag mit einem WCF-Service.

Als nächstes müssen wir einen Service erstellen und diesen starten. Das ganze fügen wir der Main-Methode in der Program.cs vom Host hinzu.


Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCF_Tut_Host
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh = new ServiceHost(typeof(HostFunctions)))
            {
                sh.Open();
                Console.WriteLine("Service started..." );
                Console.ReadLine();
                sh.Close();
            }
        }
    }
}

 

Wir erstellen einen ServiceHost sh. Damit der ServiceHost(SH) auch weiß was für Funktionen er hosten soll müssen wir ihm noch den Typen mit angeben. Das geschieht durch typeof( unsere Klasse ).
Mit sh.Open() starten wir unseren SH. Anschließend darf sich das Programm nicht gleich wieder beenden. Wir warten deshalb auf eine Benutzereingabe mit Console.Readline(). Nachdem der Benutzer Enter gedrückt hat beenden wir den SH mit sh.Close() und beenden unser Programm.

Jetzt haben wir einen SH und die passenden Funktionen dafür. Damit haben wir den Code für den Host fertig. Allerdings weiß unser Host noch nicht worauf er achten soll. Wo können sich beispielsweise Clients anmelden um die Funktionen nutzen zu können? Diese Informationen entnimmt der SH  aus der App.config. Die App.config kann erstellt werden indem ein neues Element unserem Projekt hinzugefügt wird. Das ganze nennt sich Anwendungsconfigurationsdatei.

Das ganze sieht nicht sehr spektakulär aus. Das ändern wir jetzt allerdings. In die Datei werden nun die Enpunkte eingetragen die der Service nutzen wird. Das ganze müssen wir zum Glück nicht per Hand machen. Microsoft liefert hierfür den Dienstconfigurationseditor. Dieser kann mit Visual Studio über Extras -> WCF-Dienstconf... oder im Startmenü unter Start -> Windows SDK -> Tools -> Dienstconfigurationseditor gestartet werden. In dem Editor öffnen wir nun unsere App.config aus.

Anschließend erstellen wir unter Services einen neuen Service. Der Service muss nun, wie der ServiceHost auch, wissen was wir überhaupt für Funktionen bereitstellen wollen. Wir wählen dafür unsere HostFunctions-Klasse aus. Das ganze geschieht durch die eingabe unseres Projektnamens und der Klasse. Wer schon eine .exe erstellt hat kann diese auch öffnen und erhält damit gleich alle  verfügbaren Klassen, die einen Dienstvertrag anbieten.

 

 

Im nächsten Fenster wählen wir den Kontrakt aus. In diesem Fenster sollte man das Interface auswählen, falls man dafür eines erstellt hat. Wir haben das erst einmal gelassen und können hier auch unsere HostFunctions-Klasse eintragen.
Anschließend wählen wir als Kommunikationsart HTTP. Das ist fürs erste am einfachsten. Das Ganze bei der Interoperabilität belassen wir bei Basic.
Nun kommen wir zum eigentlichen Endpunkt unseres Services. Hier kann alles mögliche Eingetragen werden. Wir haben allerdings einen HTTP-Dienst gewählt, deshalb müssen wir auch das HTTP-Protokoll verwenden. Ich habe mir für folgenden Endpunkt entschieden.

http://localhost:8500/MyService

Da wir das ganze auf unserem eigenen Rechner ausprobieren wollen ist als Ziel-IP die Loopback (localhost oder 127.0.0.1) zu wählen. Nachdem alle Einstellungen bestätigt wurden sollte noch eine kurze Zusammenfassung erscheinen.

 


 

Wir sind nun mit dem Host fertig und können ihn erstellen und starten. Wer Windows Vista oder 7 benutzt muss das Programm allerdings als Administrator ausführen. Dafür am besten gleich Visual Studio als Administrator ausführen.
Unser Host kann allerdings noch ein klein wenig verbessert werden. Die Clients, die auf den Host zugreifen, können das zwar nun tun, sie wissen allerdings nicht welche Funktionen unser Host zu Verfügung stellt. Der Host kann dafür Metainformationen zu Verfügung stellen aus dennen die Clients die Schnittstelle auslesen können. Das würde unsere Arbeit mit den Clients erheblich vereinfachen.

Um die Metainformationen über den Service preiszugeben müssen wir noch einmal unsere App.config mit dem Dienstconfigurationseditor öffnen. Wir wählen unter Advanced Service Behaviors aus und erstellen einen neuen Behavior. Diesem Behavior fügen wir ein neues Element vom Typ serviceMetadata hinzu. Ich hab den Service dabei gleich in MyMetaInformations umbenannt.

 

 

Anschließend können wir das Element bearbeiten. Wir wählen hier HttpGetEnabled aus und erstellen eine Adresse, von der die Metadaten gelesen werden können.

Ich habe mich für http://localhost:8500/MetaInfo entschieden.

 

 

Nachdem das geschehen ist können wir unseren Behavior an unseren Service zuweisen. Das geschieht indem wir unseren Service markieren und dort unter BehaviorConfiguration unseren Behavior auswählen.

 

 

Nun sind wir mit unserem Host fertig. Nachdem der Host gestartet wurde können wir unter http://localhost:8500/MetaInfo in unserem Browser die Metainformationen auslesen und wissen nun wie der Service anzusprechen ist.

Kommen wir nun zum Client. Wie gesagt können wir dank benutztem HTTP-Protokoll unseren Browser benutzen um die Metainformationen zu holen und daraus unseren Client an den Host anzupassen. Das ganze ist allerdings ziemlich kompliziert. Wir brauchen eine Proxy-Klasse die wir ansprechen um auf die Funktionen des Service zugreifen zu können und auch der Endpunkt muss bekannt sein. Dafür brauchen wir auch im Client eine App.config. Das ganze können wir zum Glück mit einem Tool lösen. Mit svcutil ist es möglich die Metainformationen gleich in eine Konfigurationsdatei und eine passende Klasse zu packen.

Wir starten svcutil über die Eingabeaufforderung von Visual Studio. Diese ist unter Start -> Microsoft Visual Studio -> Visual Studio Tools zu finden. Bevor wir allerdings damit starten können müssen wir noch unseren Host starten, damit dieser die Metainformationen über den Dienst bereitstellen kann.

Mit der Eingabe von

svcutil http://localhost:8500/MetaInfo /out:Proxy.cs /config:App.config

werden die beiden benötigten Dateien erstellt. Diese beiden Dateien kopieren wir nun in unser Projekt vom Client. Die Proxy.cs stellt nun alles bereit was wir benötigen.


Proxy.cs

//------------------------------------------------------------------------------
//
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.4927
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
//
//------------------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0" )]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="HostFunctions" )]
public interface HostFunctions
{
   
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/HostFunctions/getDate", ReplyAction="http://tempuri.org/HostFunctions/getDateResponse" )]
    string getDate();
   
    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/HostFunctions/getTime", ReplyAction="http://tempuri.org/HostFunctions/getTimeResponse" )]
    string getTime();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0" )]
public interface HostFunctionsChannel : HostFunctions, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0" )]
public partial class HostFunctionsClient : System.ServiceModel.ClientBase, HostFunctions
{
   
    public HostFunctionsClient()
    {
    }
   
    public HostFunctionsClient(string endpointConfigurationName) :
            base(endpointConfigurationName)
    {
    }
   
    public HostFunctionsClient(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }
   
    public HostFunctionsClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }
   
    public HostFunctionsClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
    {
    }
   
    public string getDate()
    {
        return base.Channel.getDate();
    }
   
    public string getTime()
    {
        return base.Channel.getTime();
    }
}
}
}

 

In der Mainfunktion des Clients erstellen wir eine Instanz von Proxy und sprechen dieses an wie jede andere Klasseninstanz auch. Im Hintergrund wird das ganze allerdings über den Host geleitet, der uns die Informationen liefert.


Programm.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WCF_Tut_Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (HostFunctionsClient proxy = new HostFunctionsClient())
            {
                Console.WriteLine( "Bei unserem Host ist es: " + proxy.getDate() + " " + proxy.getTime());
                Console.ReadLine();
            }
        }
    }
}

Wir lesen hier den Wochentag und das Datum vom Host aus und lassen es anzeigen. Nicht gerade spannend, aber für einen Anfang reicht es. Wir können nun zuerst den Host und anschließend den Client starten um unser Projekt zu testen. Wenn alles richtig ist, sollte die folgende Ausgabe erscheinen.

 


 

Falls ihr euren Host von einem anderen Computer aus starten wollt um euer Programm auf Netzwerkfähigkeit zu testen müsst ihr nur in der App.config vom Client die neue IP eintragen. Diese ist im Tag endpoint unter address zu finden. Dort einfach Localhost mit der gewünschten IP austauschen.

20.11.09 22:20