
Unter anderem durch die Aktivität im myCSharp.de-Forum ist mir aufgefallen, dass viele Entwickler doch Probleme mit der Konfiguration von WCF-Diensten haben. Zugegeben; ich bin auch kein großer Fan des .NET-Konfigurationsframeworks. Es vereinfacht manches, aber es verkompliziert auch vieles, da unnötige Werte Verwirrung stiften.
Das finde ich wirklich schade. Denn dabei ist ein WCF-Service fundamental in wenigen Zeilen geschrieben. Ihr braucht dafür nur 3 Projekte:
<img src="/contents/2016/WCFCalcExample_Projektuebersicht.png"
Das Betreiben von WCF in Konsolen-Anwendungen nennt man “self-hosted”. Entgegen dem zentralen Betreiben auf Webservern wie dem IIS, kann der WCF hier in einer Anwendung gehalten werden, um zum Beispiel eine Process-To-Process-Kommunikation zu ermöglichen; im Gegensatz zur klassischen IPC ist es hiermit jedoch einfacher auch Maschinen-übergreifend zu kommunizieren.
Beispielhaft habe ich hier ein WCF-Service (CalcService) erstellt, der die grundlegenste, bidirektionale Kommunikation darstellt: eine einfache Addition auf Server-Seite. Der Client liefert dafür die beiden Zahlen-Werte und erhält die Summe als Antwort.
Code Client:
1// Client Source
2class Program
3{
4 public const String Host = "net.tcp://localhost";
5 public const Int32 Port = 31227;
6 public const String ServiceName = "MathService";
7
8 static void Main( string[ ] args )
9 {
10 // Address
11 string svcAddress = Host + ":" + Port + "/" + ServiceName;
12
13 // Binding
14 NetTcpBinding tcpb = new NetTcpBinding( SecurityMode.Message );
15 ChannelFactory<ICalcService> chFactory = new ChannelFactory<ICalcService>( tcpb );
16
17 // Endpoint
18 EndpointAddress epAddress = new EndpointAddress( svcAddress );
19
20 // Create Channel
21 ICalcService calcService = chFactory.CreateChannel( epAddress );
22
23 Console.WriteLine( "Connected to service '" + svcAddress + "'." );
24 var result = calcService.Add( 4, 5 );
25
26 Console.WriteLine( "The result of 4+5 is '" + result + "'." );
27
28 Console.WriteLine( "Press key to quit." );
29 Console.ReadKey( );
30
31 chFactory.Close( );
32 }
33}
Code Server:
1class Program
2{
3 public const String Host = "net.tcp://localhost";
4 public const Int32 Port = 31227;
5 public const String ServiceName = "MathService";
6
7 static void Main( string[ ] args )
8 {
9 string svcAddress = Host + ":" + Port + "/" + ServiceName;
10 Uri svcUri = new Uri( svcAddress );
11
12 using ( ServiceHost sh = new ServiceHost( typeof( CalcService ), svcUri ) )
13 {
14 // Binding
15 NetTcpBinding tcpBinding = new NetTcpBinding( SecurityMode.Message );
16
17 // Behavior
18 ServiceMetadataBehavior behavior = new ServiceMetadataBehavior( );
19 sh.Description.Behaviors.Add( behavior );
20 sh.AddServiceEndpoint( typeof( IMetadataExchange ), MetadataExchangeBindings.CreateMexTcpBinding( ), "mex" );
21
22 //Endpoint
23 sh.AddServiceEndpoint( typeof( ICalcService ), tcpBinding, svcAddress );
24
25 // Open
26 sh.Open( );
27
28 Console.WriteLine( "Service started '" + svcAddress + "' ...Press key to quit." );
29 Console.ReadKey( );
30
31 Console.WriteLine( "Quit. Press key to close." );
32 Console.ReadKey( );
33
34 // Close
35 sh.Close( );
36 }
37 }
38}
Client und Server müssen beide die Schnittstelle des Services kennen. Diese Logik ist in einem dritten Projekt ausgelagert.
Code Service
1[ServiceContract]
2public interface ICalcService
3{
4 [OperationContract]
5 int Add( Int32 n1, Int32 n2 );
6}
7
8public class CalcService : ICalcService
9{
10 public int Add( Int32 n1, Int32 n2 )
11 {
12 return n1 + n2;
13 }
14}
Download / CodePlex
Der vollständige Quellcode ist unter CodePlex als WCFCalcExample verfügbar.

Comments