70-503: Service Endpoint Basics

Ten artykuł pochodzi z serii przygotowań do egzaminu 70-503: Windows Communication Foundation.

Zakładamy, że stworzyliśmy już swój serwis. Mamy zdefiniowany kontrakt serwisu, oraz określone metody, które chcemy upublicznić. Teraz chcemy wystawić go (ang. expose) światu. Do tego służy właśnie punkt wejściowy (ang. endpoint), przez który klient może się z nim komunikować.

Endpoint pozwala nam określić gdzie nasz serwis będzie się znajdował (ang. address), w jaki sposób będziemy się z nim komunikować (ang. binding), oraz co serwis robi (ang. contract). Te trzy elementy to tzw. “ABCs of Endpoints”. ABC to trzy pierwsze litery nazw elementów.

Szybki start

W Visual Studio tworzymy przykładowy projekt typu WCF Service Library. Nazwijmy go przykładowo MyNamespace.Service.

image

Wśród wygenerowanych plików interesuje nas App.config. Warto go otworzyć.

Omówienie kodu

Wygenerowany plik to XML, który zawiera deklaratywny opis serwisu. Oto wytłumaczenie kluczowych jego fragmentów.

   1: <host>
   2:   <baseAddresses>
   3:     <add baseAddress = "http://localhost:8732/Design_Time_Addresses/MyNamespace.Service/Service1/" />
   4:   </baseAddresses>
   5: </host>

Zdefiniowany został tu adres bazowy (ang. base address), czyli część wspólna dla wszystkich adresów serwisu. Wprowadźmy tu prostszy zapis - http://localhost:8732/Service1.

Uwaga: Zamiana adresu wymaga uruchomienia Visual Studio z uprawnieniami administratora. W przeciwnym wypadku otrzymamy błąd.

image

Please try changing the HTTP port to 8732 or running as Administrator.
System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://+:8732/Service1/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details). ---> System.Net.HttpListenerException: Access is denied
   at System.Net.HttpListener.AddAllPrefixes()
   at System.Net.HttpListener.Start()
   at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
   --- End of inner exception stack trace ---

W ramach znacznika endpoint zostały określone kluczowe parametry każdego punktu wejściowego.

1: <endpoint address ="" binding="wsHttpBinding" contract="MyNamespace.Service.IService1">

  • AddressURL, który identyfikuje położenie (adres) serwisu; w naszym wypadku pusty, gdyż zostanie wzięty z adresu bazowego,
  • Binding – wiązanie, określenie jaki sposób możemy otrzymać dostęp do serwisu; w naszym wypadku wykorzystany zostanie SOAP przez HTTP lub HTTPS.
    Inne możliwości to chociażby basicHttpBinding, wsDualHttpBinding, webHttpBinding, wsFederationHttpBinding, netTcpBinding, netNamedPipeBinding, netMsmqBinding, … 
    To, który binding wybierzemy zależy od kilku czynników specyficznych dla sieci oraz środowiska pracy. Przykładowo jeśli serwis jest uruchomiony na pojedynczej maszynie netNamedPipeBinding będzie najbardziej wydajny. Jeśli komunikacja ma następować pomiędzy dwoma komputerami wydajne okazać się wykorzystanie netTcpBinding lub netPeerTcpBinding. Jeśli współdziałanie pomiędzy różnymi środowiskami jest kluczową sprawą, a komunikujemy się pomiędzy komputerami bez zainstalowanego WCF’a – warto rozważyć zastosowanie basicHttpBinding lub wsHttpBinding.
  • Contract – kontrakt, który określa operacje upublicznione przez serwis; zwykle jest to nazwa interfejsu poprzedzona przestrzenią nazw (ang. namespace) projektu.

Znaczników endpoint może być dodanych wiele!

Metadane

Pod adresem http://localhost:8732/Service1/?wsdl (zakładając, że adres bazowy został zmieniony) dostępny opis serwisu w postaci pliku WSDL. Klient może uzyskać dostęp do tych danych za pomocą zwykłego zapytania HTTP-GET. Odpowiedzialne są za to dwa wiersze kodu:

   1: <!-- Wiersz 32. -->
   2: <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
   3: <!-- Wiersz 40. -->
   4: <serviceMetadata httpGetEnabled="True"/>

Zdefiniowany został tu “metadata exchange endpoint”punkt wymiany “serwujący” metadane. Ten punkt dodaje końcówkę mex do adresu HTTP wykorzystywanego przez serwis. Wykorzystuje on także IMetadataExchange jako kontrakt, oraz mexHttpBinding jako binding.

Gdybyśmy zechcieli wyłączyć udostępnianie danych opisujących serwis należy usunąć wymieniony znacznik endpoint oraz przypisać wartość False atrybutowi httpGetEnabled.

Opis za pomocą kodu

Wygenerowany XML to deklaratywny opis serwisu. To samo można zrobić z poziomu kodu. W tym celu utwórzmy nowy projekt typu Console Application, nazwijmy go MyNamespace.Host. Dodajmy w nim referencję do projektu z serwisem, oraz do komponentu System.ServiceModel. Plik App.config usuwamy. Nowy projekt ustawiamy jako domyślny.

Nowa zawartość pliku Program.cs:

   1: using System;
   2: using System.ServiceModel;
   3: using System.ServiceModel.Description;
   4:  
   5: namespace MyNamespace.Host
   6: {
   7:     class Program
   8:     {
   9:         static void Main(string[] args)
  10:         {
  11:             Uri baseAddress = new Uri("http://localhost:8732/Service1/");
  12:             ServiceHost host = new ServiceHost(typeof(MyNamespace.Service.Service1), baseAddress);
  13:  
  14:             BasicHttpBinding basicBinding = new BasicHttpBinding();
  15:             host.AddServiceEndpoint(typeof(MyNamespace.Service.IService1), basicBinding, "");
  16:  
  17:             // mex
  18:             ServiceMetadataBehavior mb;
  19:             mb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
  20:             if (mb == null)
  21:             {
  22:                 mb = new ServiceMetadataBehavior();
  23:                 mb.HttpGetEnabled = true;
  24:                 host.Description.Behaviors.Add(mb);
  25:             }
  26:             host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
  27:  
  28:             host.Open();
  29:             Console.WriteLine("Check WSDL at {0}?wsdl", baseAddress);
  30:             Console.Write("[CR] to break...");
  31:             Console.ReadLine();
  32:             host.Close();
  33:         }
  34:     }
  35: }

Uruchamiamy nasz program (F5) i cieszymy się :)

image

W następnej lekcji poznamy bardziej zaawansowane opcje związane z endpointami.

Tagi: , , , ,

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading