Sdílet prostřednictvím


Zadání adresy koncového bodu

Veškerá komunikace se službou Windows Communication Foundation (WCF) probíhá prostřednictvím jejích koncových bodů. Každý ServiceEndpoint obsahuje , Addressa Binding, a Contract. Kontrakt určuje, které operace jsou k dispozici. Vazba určuje způsob komunikace se službou a adresa určuje, kde se má služba najít. Každý koncový bod musí mít jedinečnou adresu. Adresa koncového bodu je reprezentována EndpointAddress třídou, která obsahuje identifikátor URI (Uniform Resource Identifier), který představuje adresu služby, což Identitypředstavuje identitu zabezpečení služby a kolekci volitelných Headers. Volitelné hlavičky poskytují podrobnější informace o adresování k identifikaci koncového bodu nebo interakci s ním. Hlavičky můžou například znamenat, jak zpracovat příchozí zprávu, kde má koncový bod odeslat zprávu odpovědi nebo jakou instanci služby použít ke zpracování příchozí zprávy od konkrétního uživatele, když je k dispozici více instancí.

Definice adresy koncového bodu

Ve WCF EndpointAddress modeluje odkaz na koncový bod (EPR) definovaný ve standardu WS-Adresování.

Identifikátor URI adresy pro většinu přenosů má čtyři části. Tento identifikátor URI http://www.fabrikam.com:322/mathservice.svc/secureEndpoint má například následující čtyři části:

  • Schéma: http:

  • Stroj: www.fabrikam.com

  • (Volitelné) Port: 322

  • Cesta: /mathservice.svc/secureEndpoint

Součástí modelu EPR je, že každý odkaz na koncový bod může obsahovat některé referenční parametry, které přidávají další identifikační informace. Ve WCF jsou tyto referenční parametry modelovány jako instance AddressHeader třídy.

Adresu koncového bodu pro službu je možné zadat buď imperativním použitím kódu, nebo deklarativní prostřednictvím konfigurace. Definování koncových bodů v kódu obvykle není praktické, protože vazby a adresy nasazené služby se obvykle liší od těch, které se používají při vývoji služby. Obecně je vhodnější definovat koncové body služby pomocí konfigurace místo kódu. Udržování vazby a adresování informací mimo kód jim umožňuje změnit, aniž by bylo nutné aplikaci znovu zkompilovat a znovu nasadit. Pokud nejsou v kódu nebo v konfiguraci zadány žádné koncové body, modul runtime přidá jeden výchozí koncový bod na každou základní adresu pro každou smlouvu implementovanou službou.

Existují dva způsoby, jak zadat adresy koncových bodů pro službu ve WCF. Můžete zadat absolutní adresu pro každý koncový bod přidružený ke službě nebo můžete zadat základní adresu pro ServiceHost službu a pak zadat adresu pro každý koncový bod přidružený k této službě, který je definován vzhledem k této základní adrese. Každý z těchto postupů můžete použít k určení adres koncových bodů pro službu v konfiguraci nebo kódu. Pokud nezadáte relativní adresu, služba použije základní adresu. Pro službu můžete mít také více základních adres, ale každá služba má pro každý přenos povolenou jenom jednu základní adresu. Pokud máte více koncových bodů, z nichž každá je nakonfigurovaná s jinou vazbou, musí být jejich adresy jedinečné. Koncové body, které používají stejnou vazbu, ale různé kontrakty můžou používat stejnou adresu.

Při hostování se službou ServiceHost IIS nespravujete instanci sami. Základní adresa je vždy adresa zadaná v souboru .svc pro službu při hostování ve službě IIS. Proto je nutné použít relativní adresy koncových bodů pro koncové body služby hostované službou IIS. Poskytnutí plně kvalifikované adresy koncového bodu může vést k chybám při nasazování služby. Další informace naleznete v tématu Nasazení služby WCF hostované Internetová informační služba.

Definování adres koncových bodů v konfiguraci

K definování koncového bodu v konfiguračním souboru použijte prvek koncového <bodu> .

<configuration>
  <system.serviceModel>
    <services>
      <service name="UE.Samples.HelloService"
               behaviorConfiguration="HelloServiceBehavior">
        <endpoint address="/Address1"
                  binding="basicHttpBinding" 
                  contract="UE.Samples.IHello"/>

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="HelloServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Open Při volání metody (to znamená, když se hostitelská aplikace pokusí spustit službu), systém vyhledá <prvek služby> s atributem name, který určuje "UE. Samples.HelloService. <Pokud se najde prvek služby>, systém načte zadanou třídu a vytvoří koncové body pomocí definic koncových bodů zadaných v konfiguračním souboru. Tento mechanismus umožňuje načíst a spustit službu se dvěma řádky kódu a zároveň zachovat vazbu a adresování informací mimo kód. Výhodou tohoto přístupu je, že tyto změny je možné provést, aniž by bylo nutné aplikaci znovu zkompilovat nebo znovu nasadit.

Volitelná záhlaví jsou deklarována v <hlavičkách>. Následuje příklad prvků použitých k určení koncových bodů pro službu v konfiguračním souboru, který rozlišuje mezi dvěma hlavičkami: "Gold" od klientů Standard od http://tempuri1.org/ klientů Standard .http://tempuri2.org/ Klient, který tuto službu volá, musí mít v konfiguračním souboru odpovídající hlavičky>.<

<configuration>
  <system.serviceModel>
    <services>
      <service name="UE.Samples.HelloService"
               behaviorConfiguration="HelloServiceBehavior">
        <endpoint address="/Address1"
                  binding="basicHttpBinding" 
                  contract="UE.Samples.IHello">
          <headers>
            <Member xmlns="http://tempuri1.org/">Gold</Member>
          </headers>
        </endpoint>
        <endpoint address="/Address2"
          binding="basicHttpBinding" 
          contract="UE.Samples.IHello">
          <headers>
            <Member xmlns="http://tempuri2.org/">Silver</Member>
          </headers>
        </endpoint>

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="HelloServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Záhlaví je také možné nastavit pro jednotlivé zprávy místo všech zpráv v koncovém bodu (jak je znázorněno dříve). To se provádí pomocí OperationContextScope vytvoření nového kontextu v klientské aplikaci pro přidání vlastní hlavičky do odchozí zprávy, jak je znázorněno v následujícím příkladu.

SampleServiceClient wcfClient = new SampleServiceClient(new InstanceContext(this));
try
{
  using (OperationContextScope scope = new OperationContextScope(wcfClient.InnerChannel))
  {
    MessageHeader header
      = MessageHeader.CreateHeader(
      "Service-Bound-CustomHeader",
      "http://Microsoft.WCF.Documentation",
      "Custom Happy Value."
      );
    OperationContext.Current.OutgoingMessageHeaders.Add(header);

    // Making calls.
    Console.WriteLine("Enter the greeting to send: ");
    string greeting = Console.ReadLine();

    //Console.ReadLine();
    header = MessageHeader.CreateHeader(
        "Service-Bound-OneWayHeader",
        "http://Microsoft.WCF.Documentation",
        "Different Happy Value."
      );
    OperationContext.Current.OutgoingMessageHeaders.Add(header);

    // One-way
    wcfClient.Push(greeting);
    this.wait.WaitOne();

    // Done with service.
    wcfClient.Close();
    Console.WriteLine("Done!");
    Console.ReadLine();
  }
}
catch (TimeoutException timeProblem)
{
  Console.WriteLine("The service operation timed out. " + timeProblem.Message);
  Console.ReadLine();
  wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
  Console.WriteLine("There was a communication problem. " + commProblem.Message);
  Console.ReadLine();
  wcfClient.Abort();
}
Dim wcfClient As New SampleServiceClient(New InstanceContext(Me))
Try
    Using scope As New OperationContextScope(wcfClient.InnerChannel)
        Dim header As MessageHeader = MessageHeader.CreateHeader("Service-Bound-CustomHeader", _
                            "http://Microsoft.WCF.Documentation", "Custom Happy Value.")
        OperationContext.Current.OutgoingMessageHeaders.Add(header)

        ' Making calls.
        Console.WriteLine("Enter the greeting to send: ")
        Dim greeting As String = Console.ReadLine()

        'Console.ReadLine();
        header = MessageHeader.CreateHeader("Service-Bound-OneWayHeader", _
                                            "http://Microsoft.WCF.Documentation", "Different Happy Value.")
        OperationContext.Current.OutgoingMessageHeaders.Add(header)

        ' One-way
        wcfClient.Push(greeting)
        Me.wait.WaitOne()

        ' Done with service. 
        wcfClient.Close()
        Console.WriteLine("Done!")
        Console.ReadLine()
    End Using
Catch timeProblem As TimeoutException
    Console.WriteLine("The service operation timed out. " & timeProblem.Message)
    Console.ReadLine()
    wcfClient.Abort()
Catch commProblem As CommunicationException
    Console.WriteLine("There was a communication problem. " & commProblem.Message)
    Console.ReadLine()
    wcfClient.Abort()
End Try

Adresa koncového bodu v metadatech

Adresa koncového bodu je reprezentována v jazyce WSDL (Web Services Description Language) jako element WS-Address EndpointReference (EPR) uvnitř elementu odpovídajícího koncového wsdl:port bodu. EPR obsahuje adresu koncového bodu a také všechny vlastnosti adresy. Všimněte si, že EPR uvnitř wsdl:port nahrazuje soap:Address , jak je vidět v následujícím příkladu.

Definování adres koncových bodů v kódu

Adresu koncového bodu je možné vytvořit v kódu s EndpointAddress třídou. Identifikátor URI zadaný pro adresu koncového bodu může být plně kvalifikovaná cesta nebo cesta, která je relativní vzhledem k základní adrese služby. Následující kód ukazuje, jak vytvořit instanci EndpointAddress třídy a přidat ji do ServiceHost instance, která je hostitelem služby.

Následující příklad ukazuje, jak zadat úplnou adresu koncového bodu v kódu.

Uri baseAddress = new Uri("http://localhost:8000/HelloService");
string address = "http://localhost:8000/HelloService/MyService";

using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
    serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), address);
    serviceHost.Open();
    Console.WriteLine("Press <enter> to terminate service");
    Console.ReadLine();
    serviceHost.Close();
}

Následující příklad ukazuje, jak přidat relativní adresu ("MyService") na základní adresu hostitele služby.

Uri baseAddress = new Uri("http://localhost:8000/HelloService");

using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
    serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), "MyService");
    serviceHost.Open();
    Console.WriteLine("Press <enter> to terminate service");
    Console.ReadLine();
    serviceHost.Close();
}

Poznámka:

ServiceDescription Vlastnosti aplikace služby nesmí být změněny po metodě na OnOpeningServiceHostBase. Některé členy, například Credentials vlastnost a AddServiceEndpoint metody zapnuty ServiceHostBase a ServiceHost, vyvolat výjimku v případě změny po tomto bodu. Ostatní vám umožňují je upravovat, ale výsledek je nedefinovaný.

Podobně v klientovi ServiceEndpoint nesmí být hodnoty změněny po volání OnOpening na ChannelFactorystraně . Vlastnost Credentials vyvolá výjimku, pokud je změněna po tomto bodu. Ostatní hodnoty popisu klienta je možné upravit bez chyby, ale výsledek není definován.

Bez ohledu na to, zda je služba nebo klient, doporučujeme před voláním Openupravit popis .

Použití výchozích koncových bodů

Pokud nejsou zadány žádné koncové body v kódu nebo v konfiguraci, modul runtime poskytuje výchozí koncové body přidáním jednoho výchozího koncového bodu na každou základní adresu pro každý kontrakt služby implementovaný službou. Základní adresu lze zadat v kódu nebo v konfiguraci a výchozí koncové body jsou přidány při Open zavolání na ServiceHost.

Pokud jsou koncové body explicitně zadané, je možné výchozí koncové body přidat voláním AddDefaultEndpointsServiceHost před voláním Open. Další informace o výchozích koncových bodech, vazbách a chování najdete v tématu Zjednodušená konfigurace a zjednodušená konfigurace pro služby WCF.

Viz také