niedziela, 15 września 2013

70-513 Udostępnianie serwisu WCF

Aby ktoś mógł skorzystać, ze stworzonego przez na serwisu należy go udostępnić.

Adres
Adres wskazuje gdzie znajduje się nasz serwis składa się z 4 składowych: schema, nazwa hosta, portu, ścieżki (przeważnie nazwa serwisu). Przykład: http://www.contoso.com/OrderService/

Binding
Binding definiuje sposób, w jaki będzie można się dostać do serwisu. Są to elementy takie jak protokół, SSL. WCF udostępnia domyślnie kilka predefiniowanych możliwości komunikacji:
  • basicHttpBinding - HTTP, HTTPS, MTOM
  • wsHttpBinding - HTTP, HTTPS, MTOM - oferuje niezawodność, tranzakcyjność, bezpieczeństwo
  • wsDualHttpBinding - dwukierunkowa komunikacja 
  • webHttpBinding - przekazuje dane przez HTTP lub HTTPS nie korzystając z formatu protokołu SOAP - przydatny w przypadku gdy klient nie wymaga protokołu SOAP
  • wsFederationHttpBinding - zapewnia bezpieczeństwo pomiędzy różnymi systemami autoryzacji i autentykacji
  • netTcpBinding - przesyłanie danych po TCP
  • netNamedPipeBinding - jeżeli serwis będzie używany na jednym komputerze
  • netMsmqBinding - komunikacja pomiędzy dwoma komputerami
  • netPeerTcpBinding - komunikacja Peer-To-Peer pomiędzy komputerami
  • msmqIntegrationBinding - dla istniejących aplikacji napisanych w C++ używających do komunikacji MSMQ
  • basicHttpContextBinding - wsparcie plików cookie dla protokołu HTTP
  • netTcpContextBinding, netTcpContextBinding, wsHttpContextBinding - umożliwia użycie nagłówka w celu wymiany komunikatów

Contract
Określa operacje udostępniane przez serwis i jest to przeważnie nazwa interfejsu poprzedzona przestrzenią nazw.

Powyższe składowe można zadeklarować zarówno w kodzie jak i konfiguracji XML. XML jest preferowanym sposobem, gdyż w przypadku zmiany np. adresu nie ma konieczności kompilowania całej aplikacji od początku, a jedyna zmiana będzie dotyczyła pliku konfiguracyjnego.

Przykład konfiguracji w XML:

Code:
  <system.serviceModel>
    <services>
      <service name="WcfExposingService.OrderService">
        <endpoint address="http://localhost:8000/OrderService/" binding="basicHttpBinding" 
                  contract="WcfExposingService.IOrderService"/>
      </service>
    </services>
  </system.serviceModel>

Dla jednego serwisu można skonfigurować wiele sposobów komunikacji (endpoint), tak więc do jego serwisu możemy odnosić się poprzez protokół HTTP, TCP czy też inny sposób. W tym przypadku należy pamiętać tylko o tym, aby każdy z tych sposobów posiadał inny adres ekspozycji serwisu.
Aby sobie ułatwić pracę podczas definiowania wielu adresów, można skorzystać z właściwości base address i dodać do listy, bazowe adresy, które następnie zostaną uzupełnione odpowiednią końcówką. Uwaga! w przypadku hostowania na IIS bazowe adresy nie są brane pod uwagę, gdyż są mapowane na ścieżkę wirtualną do katalogu gdzie znajdują się pliki serwisu.
W przypadku adresu bazowego WCF rozpoznaje z jakim bindingiem ma do czynienia a następnie dobiera odpowiedni adres z dostępnej listy.
Przykład takiej konfiguracji:

Code:
    <services>
      <service name="WcfExposingService.OrderService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:17354/OrderService/"/>
            <add baseAddress="net.tcp://localhost:17354/OrderService/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding"
                  contract="WcfExposingService.IOrderService"/>
        <endpoint address="secure" binding="wsHttpBinding"
                  contract="WcfExposingService.IOrderService"/>
        <endpoint address="" binding="NetTcpBinding"
          contract="WcfExposingService.IOrderService"/>
      </service>
    </services>

Oraz konfiguracja w kodzie C#:

Code:
            Uri httpAddress = new Uri("http://localhost:8000/OrderService/");
            Uri tcpAddress = new Uri("net.tcp://localhost:8000/OrderService/");
            Uri[] baseAddresses = {httpAddress, tcpAddress};

            var serviceHost = new ServiceHost(typeof (OrderService), baseAddresses);
            var basicHttpBinding = new BasicHttpBinding();
            var wsHttpBinding = new WSHttpBinding();
            var netTcpBinding = new NetTcpBinding();

            serviceHost.AddServiceEndpoint(typeof (IOrderService), basicHttpBinding, "");
            serviceHost.AddServiceEndpoint(typeof(IOrderService), wsHttpBinding, "secure");
            serviceHost.AddServiceEndpoint(typeof(IOrderService), netTcpBinding, "");



Publikowanie metadanych
Metadane publikujemy za pomocą bindowania o typie mexHttpBinding. Metadane możemy pobrać dla serwisu za pomocą składni: nazwa_serwisu.svc?wsdl. Definiowanie w XML:

Code:
  <system.serviceModel>
    <services>
      <service name="WcfExposingService.OrderService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:17354/OrderService/"/>
            <add baseAddress="net.tcp://localhost:17354/OrderService/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding"
                  contract="WcfExposingService.IOrderService"/>
        <endpoint address="secure" binding="wsHttpBinding"
                  contract="WcfExposingService.IOrderService"/>
        <endpoint address="" binding="NetTcpBinding"
          contract="WcfExposingService.IOrderService"/>
        <endpoint address="mex" binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MexGet">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

I to samo w kodzie:

Code:
            ServiceMetadataBehavior serviceMetadataBehavior =
                serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (serviceMetadataBehavior != null)
            {
                serviceMetadataBehavior = new ServiceMetadataBehavior();
                serviceMetadataBehavior.HttpGetEnabled = true;
                serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
            }
            serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                           MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

Brak komentarzy:

Prześlij komentarz