Delen via


Transport: UDP

Het UDP Transport-voorbeeld laat zien hoe u UDP unicast en multicast implementeert als een aangepast WCF-transport (Windows Communication Foundation). De steekproef beschrijft de aanbevolen procedure voor het creëren van een aangepast transport in WCF, door gebruik te maken van de kanaalinfrastructuur en de beste WCF-praktijken te volgen. De stappen voor het maken van een aangepast transport zijn als volgt:

  1. Bepaal welke van de kanalen Message Exchange Patterns (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel of IReplyChannel) uw ChannelFactory en ChannelListener zullen ondersteunen. Bepaal vervolgens of u de sessievolle variaties van deze interfaces wilt ondersteunen.

  2. Maak een kanalenfabriek en luisteraar die uw Message Exchange-patroon ondersteunen.

  3. Zorg ervoor dat eventuele netwerkspecifieke uitzonderingen worden genormaliseerd naar de juiste afgeleide klasse van CommunicationException.

  4. Voeg een <bindingselement> toe waarmee het aangepaste transport wordt toegevoegd aan een kanaalstack. Zie Een bindingselement toevoegen voor meer informatie.

  5. Voeg een sectie voor de extensie voor bindingselementen toe om het nieuwe bindingselement beschikbaar te maken voor het configuratiesysteem.

  6. Voeg metagegevensextensies toe om mogelijkheden te communiceren met andere eindpunten.

  7. Voeg een binding toe waarmee een stapel bindingselementen vooraf wordt geconfigureerd volgens een goed gedefinieerd profiel. Zie Een standaardbinding toevoegen voor meer informatie.

  8. Voeg een bindingssectie en een bindingsconfiguratie-element toe om de binding beschikbaar te maken voor het configuratiesysteem. Zie Configuratieondersteuning toevoegen voor meer informatie.

Berichtuitwisselingspatronen

De eerste stap bij het schrijven van een aangepast transport is bepalen welke Message Exchange Patterns vereist zijn voor het transport. Er zijn drie parlementsleden waaruit u kunt kiezen:

  • Datagram (IInputChannel/IOutputChannel)

    Wanneer u een datagram-MEP gebruikt, verzendt een client een bericht met behulp van een 'fire and forget'-uitwisseling. Een 'fire-and-forget'-transactie is er een die een out-of-band bevestiging van geslaagde levering vereist. Het bericht gaat mogelijk verloren tijdens de overdracht en bereikt nooit de service. Als de verzendbewerking is voltooid aan het clienteindpunt, wordt niet gegarandeerd dat het externe eindpunt het bericht heeft ontvangen. Het datagram is een fundamentele bouwsteen voor berichten, omdat u er uw eigen protocollen op kunt bouwen, inclusief betrouwbare protocollen en veilige protocollen. Client-datagramkanalen implementeren de IOutputChannel-interface en service-datagramkanalen implementeren de IInputChannel-interface.

  • Request-Response (IRequestChannel/IReplyChannel)

    In dit MEP wordt een bericht verzonden en wordt er een antwoord ontvangen. Het patroon bestaat uit aanvraag-antwoordparen. Voorbeelden van aanvragen-antwoord-aanroepen zijn externe procedure-aanroepen (RPC) en browser-GET's. Dit patroon wordt ook wel Half-Duplex genoemd. In dit MEP implementeren klantkanalen IRequestChannel en servicekanalen IReplyChannel.

  • Duplex (IDuplexChannel)

    Met het duplex-MEP kan een willekeurig aantal berichten worden verzonden door een client en in elke willekeurige volgorde worden ontvangen. Het duplex-MEP is net als een telefoongesprek, waarbij elk woord dat wordt gesproken een bericht is. Omdat in dit MEP beide zijden kunnen verzenden en ontvangen, wordt de interface door de client- en servicekanalen geïmplementeerd als IDuplexChannel.

Elk van deze leden kan ook sessies ondersteunen. De toegevoegde functionaliteit van een sessiebewust kanaal is dat alle berichten die op een kanaal worden verzonden en ontvangen, worden gecorreleerd. Het Request-Response patroon is een zelfstandige sessie met twee berichten, omdat de aanvraag en het antwoord gecorreleerd zijn. Het Request-Response patroon dat sessies ondersteunt, houdt daarentegen in dat alle aanvraag-/antwoordparen op dat kanaal met elkaar zijn gecorreleerd. Hiermee krijgt u in totaal zes MEP's—Datagram, Request-Response, Duplex, Datagram met sessies, Request-Response met sessies en Duplex met sessies—waaruit u kunt kiezen.

Opmerking

Voor het UDP-transport is het enige MEP dat wordt ondersteund Datagram, omdat UDP inherent een 'fire and forget'-protocol is.

Het ICommunicationObject en de levenscyclus van het WCF-object

WCF heeft een algemene statusmachine die wordt gebruikt voor het beheren van de levenscyclus van objecten zoals IChannel, IChannelFactoryen IChannelListener die worden gebruikt voor communicatie. Er zijn vijf statussen waarin deze communicatieobjecten kunnen bestaan. Deze statussen worden vertegenwoordigd door de CommunicationState opsomming en zijn als volgt:

  • Gemaakt: Dit is de status van een ICommunicationObject wanneer deze voor het eerst wordt geïnstantieerd. Er treedt geen invoer/uitvoer (I/O) op in deze status.

  • Openen: Objecten gaan over naar deze staat wanneer Open wordt aangeroepen. Op dit moment worden eigenschappen onveranderbaar gemaakt en kunnen invoer/uitvoer beginnen. Deze overgang is alleen geldig vanuit de status Gemaakt.

  • Geopend: Objecten worden naar deze status overgezet wanneer het geopende proces is voltooid. Deze overgang is alleen geldig vanaf de status Openen. Op dit moment is het object volledig bruikbaar voor overdracht.

  • Sluiten: Objecten worden overgestapt naar deze status wanneer Close wordt aangeroepen voor een probleemloos afsluiten. Deze overgang is alleen geldig vanuit de status Geopend.

  • Gesloten: In de gesloten toestand zijn objecten niet meer bruikbaar. Over het algemeen is de meeste configuratie nog steeds toegankelijk voor inspectie, maar er kan geen communicatie plaatsvinden. Deze status is gelijk aan verwijdering.

  • Defect: In de status Defect zijn objecten toegankelijk voor inspectie, maar kunnen ze niet meer worden gebruikt. Wanneer er een niet-herstelbare fout optreedt, verandert het object in deze status. De enige geldige overgang van deze status is in de Closed status.

Er zijn gebeurtenissen die plaatsvinden bij elke statusovergang. De Abort methode kan op elk gewenst moment worden aangeroepen en zorgt ervoor dat het object onmiddellijk wordt overgestapt van de huidige status in de gesloten status. Het aanroepen Abort beëindigt eventuele onvoltooide werkzaamheden.

Channel Factory en Channel Listener

De volgende stap bij het schrijven van een aangepast transport is het maken van een implementatie van IChannelFactory voor clientkanalen en van IChannelListener voor servicekanalen. De kanaallaag maakt gebruik van een fabriekspatroon voor het maken van kanalen. WCF biedt hulpmiddelen voor basis klassen voor dit proces.

In dit voorbeeld bevindt de factory-implementatie zich in UdpChannelFactory.cs en bevindt de listener-implementatie zich in UdpChannelListener.cs. De IChannel implementaties bevinden zich in UdpOutputChannel.cs en UdpInputChannel.cs.

De UDP-kanaalfabriek

De UdpChannelFactory komt voort uit ChannelFactoryBase. Het voorbeeld overschrijft GetProperty om toegang te bieden tot de berichtversie van de berichtcoderingsprogramma. Het voorbeeld vervangt OnClose ook zodat we ons exemplaar kunnen afbreken wanneer de status van de statusmachine verandert.

Het UDP-uitvoerkanaal

De UdpOutputChannel implementeert IOutputChannel. De constructor valideert de argumenten en bouwt een doelobject EndPoint op basis van de EndpointAddress doorgegeven object.

this.socket = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

Het kanaal kan rustig of geforceerd worden gesloten. Als het kanaal zorgvuldig wordt gesloten, wordt de socket gesloten en wordt de methode van de basisklasse OnClose aangeroepen. Als dit een uitzondering genereert, roept de infrastructuur Abort aan om ervoor te zorgen dat het kanaal wordt opgeschoond.

this.socket.Close(0);

Vervolgens implementeren Send() en BeginSend()/EndSend(). Dit is onderverdeeld in twee hoofdsecties. Eerst serialiseren we het bericht in een bytematrix.

ArraySegment<byte> messageBuffer = EncodeMessage(message);

Vervolgens sturen we de resulterende gegevens op de kabel.

this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count, SocketFlags.None, this.remoteEndPoint);

De UdpChannelListener

Het UdpChannelListener dat door het voorbeeld wordt geïmplementeerd, is afgeleid van de ChannelListenerBase klasse. Er wordt één UDP-socket gebruikt om datagrammen te ontvangen. De OnOpen methode ontvangt gegevens met behulp van de UDP-socket in een asynchrone lus. De gegevens worden vervolgens geconverteerd naar berichten met behulp van het Message Encoding Framework.

message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);

Omdat hetzelfde datagramkanaal berichten vertegenwoordigt die afkomstig zijn van een aantal bronnen, is het UdpChannelListener een singleton-listener. Er is maximaal één actieve IChannel aan deze listener tegelijk gekoppeld. Het voorbeeld genereert alleen een andere als een kanaal dat door de AcceptChannel methode wordt geretourneerd, vervolgens wordt afgesloten. Wanneer een bericht wordt ontvangen, wordt het in dit singleton-kanaal geplaatst.

UdpInvoerKanaal

De UdpInputChannel klasse implementeert IInputChannel. Het bestaat uit een wachtrij met binnenkomende berichten die worden gevuld door de socket van de UdpChannelListener. Deze berichten worden door de IInputChannel.Receive methode uit de wachtrij verwijderd.

Een bindingselement toevoegen

Nu de factory's en kanalen zijn gebouwd, moeten we ze via een binding blootstellen aan de ServiceModel-runtime. Een binding is een verzameling bindingselementen die de communicatiestack vertegenwoordigt die is gekoppeld aan een serviceadres. Elk element in de stack wordt vertegenwoordigd door een <bindingselement> .

In het voorbeeld is UdpTransportBindingElementhet bindingselement , dat is afgeleid van TransportBindingElement. Het overschrijft de volgende methoden om de fabrieken te bouwen die aan onze binding zijn gekoppeld.

public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
    return (IChannelFactory<TChannel>)(object)new UdpChannelFactory(this, context);
}

public IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
    return (IChannelListener<TChannel>)(object)new UdpChannelListener(this, context);
}

Het bevat ook leden voor het BindingElement klonen en het teruggeven van ons schema (soap.udp).

Ondersteuning voor metagegevens toevoegen voor een transportbindingselement

Om ons transport te integreren in het metagegevenssysteem, moeten we zowel het importeren als exporteren van beleid ondersteunen. Hierdoor kunnen we clients van onze binding genereren via het Hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe).

WSDL-ondersteuning toevoegen

Het transportbindingselement in een binding is verantwoordelijk voor het exporteren en importeren van adresseringsinformatie in metagegevens. Wanneer u een SOAP-binding gebruikt, moet het transportbindingselement ook een juiste transport-URI in metagegevens exporteren.

WSDL Exporteren

Als u adresseringsgegevens wilt exporteren, wordt de UdpTransportBindingElementIWsdlExportExtension interface geïmplementeerd. De ExportEndpoint methode voegt de juiste adresseringsinformatie toe aan de WSDL-poort.

if (context.WsdlPort != null)
{
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}

De UdpTransportBindingElement implementatie van de ExportEndpoint methode exporteert ook een transport-URI wanneer het eindpunt een SOAP-binding gebruikt.

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}

WSDL Importeren

Als u het WSDL-importsysteem wilt uitbreiden voor het importeren van de adressen, moet u de volgende configuratie toevoegen aan het configuratiebestand voor Svcutil.exe, zoals wordt weergegeven in het Svcutil.exe.config-bestand.

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <policyImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

Wanneer u Svcutil.exerunt, zijn er twee mogelijkheden om Svcutil.exe de WSDL-importextensies te laten laden.

  1. Wijs Svcutil.exe naar ons configuratiebestand met behulp van het bestand< /SvcutilConfig:>.

  2. Voeg de configuratiesectie toe aan Svcutil.exe.config in dezelfde map als Svcutil.exe.

Het UdpBindingElementImporter type implementeert de IWsdlImportExtension interface. De ImportEndpoint methode importeert het adres uit de WSDL-poort.

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
    ImportAddress(context);
}

Beleidsondersteuning toevoegen

Het aangepaste bindingselement kan beleidsverklaringen exporteren in de WSDL-binding voor een service-eindpunt om de mogelijkheden van dat bindingselement uit te drukken.

Beleidsexport

Het UdpTransportBindingElement type implementeert IPolicyExportExtension om ondersteuning toe te voegen voor het exporteren van beleid. Als gevolg hiervan omvat System.ServiceModel.MetadataExporterUdpTransportBindingElement in de generatie van beleid voor elke binding die System.ServiceModel.MetadataExporter bevat.

In IPolicyExportExtension.ExportPolicyvoegen we een assertie toe voor UDP en een andere assertie als we zich in de multicast-modus bevinden. Dit komt doordat de multicastmodus van invloed is op de manier waarop de communicatiestack wordt samengesteld en dus moet worden gecoördineerd tussen beide zijden.

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();
XmlDocument xmlDocument = new XmlDocument();
bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));
if (Multicast)
{
    bindingAssertions.Add(xmlDocument.CreateElement(
        UdpPolicyStrings.Prefix,
        UdpPolicyStrings.MulticastAssertion,
        UdpPolicyStrings.UdpNamespace));
}

Omdat aangepaste transportbindingselementen verantwoordelijk zijn voor het afhandelen van adressering, moet de IPolicyExportExtension-implementatie op de UdpTransportBindingElement ook de juiste WS-Addressing-beleidsverklaringen exporteren om aan te geven welke versie van WS-Addressing wordt gebruikt.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);

Beleid importeren

Als u het systeem voor het importeren van beleid wilt uitbreiden, moet u de volgende configuratie toevoegen aan het configuratiebestand voor Svcutil.exe, zoals wordt weergegeven in het bestand Svcutil.exe.config.

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <policyImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

Vervolgens implementeren IPolicyImporterExtension we vanuit onze geregistreerde klasse (UdpBindingElementImporter). In ImportPolicy(), bekijken we de asserties in onze naamruimte. We verwerken de asserties voor het genereren van het transport en controleren of het multicast is. We moeten ook de asserties verwijderen die we verwerken uit de lijst met bindingsverklaringen. Nogmaals, bij het uitvoeren van Svcutil.exezijn er twee opties voor integratie:

  1. Wijs Svcutil.exe naar ons configuratiebestand met behulp van het bestand< /SvcutilConfig:>.

  2. Voeg de configuratiesectie toe aan Svcutil.exe.config in dezelfde map als Svcutil.exe.

Een standaardbinding toevoegen

Ons bindingselement kan op de volgende twee manieren worden gebruikt:

  • Via een aangepaste binding: met een aangepaste binding kan de gebruiker een eigen binding maken op basis van een willekeurige set bindingselementen.

  • Door gebruik te maken van een door het systeem geleverde binding die ons bindingselement bevat. WCF biedt een aantal van deze door het systeem gedefinieerde bindingen, zoals BasicHttpBinding, NetTcpBindingen WsHttpBinding. Elk van deze bindingen is gekoppeld aan een goed gedefinieerd profiel.

Het voorbeeld implementeert profielbinding in SampleProfileUdpBinding, dat afkomstig is van Binding. De SampleProfileUdpBinding bevat maximaal vier bindingselementen erin: UdpTransportBindingElement, TextMessageEncodingBindingElement CompositeDuplexBindingElementen ReliableSessionBindingElement.

public override BindingElementCollection CreateBindingElements()
{
    BindingElementCollection bindingElements = new BindingElementCollection();
    if (ReliableSessionEnabled)
    {
        bindingElements.Add(session);
        bindingElements.Add(compositeDuplex);
    }
    bindingElements.Add(encoding);
    bindingElements.Add(transport);
    return bindingElements.Clone();
}

Een aangepaste standaardbindingimporteur toevoegen

Standaard herkennen en importeren Svcutil.exe en het WsdlImporter-type systeemgedefinieerde bindingen. Anders wordt de binding geïmporteerd als een CustomBinding exemplaar. Om Svcutil.exe en de WsdlImporter te kunnen importeren, fungeert de SampleProfileUdpBinding ook als een aangepaste standaardbindingimporteur voor de UdpBindingElementImporter.

Een aangepaste standaardbindingimporteur implementeert de ImportEndpoint methode op de IWsdlImportExtension interface om het CustomBinding exemplaar te onderzoeken dat is geïmporteerd uit metagegevens om te zien of het kan zijn gegenereerd door een specifieke standaardbinding.

if (context.Endpoint.Binding is CustomBinding)
{
    Binding binding;
    if (transportBindingElement is UdpTransportBindingElement)
    {
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the
        //generated config file for better typed generation.
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))
        {
            binding.Name = context.Endpoint.Binding.Name;
            binding.Namespace = context.Endpoint.Binding.Namespace;
            context.Endpoint.Binding = binding;
        }
    }
}

Over het algemeen omvat het implementeren van een aangepaste standaardbindingimporteur het controleren van de eigenschappen van de geïmporteerde bindingselementen om te controleren of alleen eigenschappen die door de standaardbinding kunnen zijn ingesteld, zijn gewijzigd en alle andere eigenschappen de standaardwaarden zijn. Een basisstrategie voor het implementeren van een standaardbindingimporteur is het maken van een exemplaar van de standaardbinding, het doorgeven van de eigenschappen van de bindingselementen aan het standaardbindingexemplaren dat door de standaardbinding wordt ondersteund en het vergelijken van de bindingselementen van de standaardbinding met de geïmporteerde bindingselementen.

Configuratieondersteuning toevoegen

Om ons transport via configuratie beschikbaar te maken, moeten we twee configuratiesecties implementeren. De eerste is een BindingElementExtensionElement voor UdpTransportBindingElement. Dit is zo dat CustomBinding implementaties kunnen verwijzen naar ons bindingselement. De tweede is een Configuration voor onze SampleProfileUdpBinding.

Uitbreidingselement van bindingselement

De sectie UdpTransportElement is een BindingElementExtensionElement die UdpTransportBindingElement blootstelt aan het configuratiesysteem. Met enkele eenvoudige overschrijvingen definiëren we de naam van de configuratiesectie, het type van ons bindingselement en hoe we ons bindingselement maken. Vervolgens kunnen we de extensiesectie registreren in een configuratiebestand, zoals wordt weergegeven in de volgende code.

<configuration>
  <system.serviceModel>
    <extensions>
      <bindingElementExtensions>
        <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
      </bindingElementExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

Naar de extensie kan worden verwezen vanuit aangepaste bindingen om UDP als transport te gebruiken.

<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
       <binding configurationName="UdpCustomBinding">
         <udpTransport/>
       </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Bindend gedeelte

De sectie SampleProfileUdpBindingCollectionElement is een StandardBindingCollectionElement die SampleProfileUdpBinding blootstelt aan het configuratiesysteem. Het grootste deel van de implementatie wordt gedelegeerd aan de SampleProfileUdpBindingConfigurationElement, die is afgeleid van StandardBindingElement. De SampleProfileUdpBindingConfigurationElement heeft eigenschappen die overeenkomen met de eigenschappen op SampleProfileUdpBinding, en functies om te koppelen vanuit de ConfigurationElement binding. Ten slotte overschrijft u de OnApplyConfiguration methode in onze SampleProfileUdpBinding, zoals wordt weergegeven in de volgende voorbeeldcode.

protected override void OnApplyConfiguration(string configurationName)
{
    if (binding == null)
        throw new ArgumentNullException("binding");

    if (binding.GetType() != typeof(SampleProfileUdpBinding))
    {
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
            "Invalid type for binding. Expected type: {0}. Type passed in: {1}.",
            typeof(SampleProfileUdpBinding).AssemblyQualifiedName,
            binding.GetType().AssemblyQualifiedName));
    }
    SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;

    udpBinding.OrderedSession = this.OrderedSession;
    udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
    udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
    if (this.ClientBaseAddress != null)
        udpBinding.ClientBaseAddress = ClientBaseAddress;
}

Als u deze handler wilt registreren bij het configuratiesysteem, voegen we de volgende sectie toe aan het relevante configuratiebestand.

<configuration>
  <configSections>
     <sectionGroup name="system.serviceModel">
        <sectionGroup name="bindings">
          <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
        </sectionGroup>
     </sectionGroup>
  </configSections>
</configuration>

Er kan vervolgens naar worden verwezen vanuit de configuratiesectie serviceModel.

<configuration>
  <system.serviceModel>
    <client>
      <endpoint configurationName="calculator"
                address="soap.udp://localhost:8001/"
                bindingConfiguration="CalculatorServer"
                binding="sampleProfileUdpBinding"
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

De UDP-testservice en UDP-client

Testcode voor het gebruik van dit voorbeeldtransport is beschikbaar in de mappen UdpTestService en UdpTestClient. De servicecode bestaat uit twee tests: één test stelt bindingen en eindpunten van code in en de andere doet dit via de configuratie. Beide tests maken gebruik van twee eindpunten. Eén eindpunt maakt gebruik van de SampleUdpProfileBinding met <ReliableSession> ingesteld op true. Het andere eindpunt maakt gebruik van een aangepaste binding met UdpTransportBindingElement. Dit is equivalent aan het gebruik van SampleUdpProfileBinding met <reliableSession> ingesteld op false. Beide tests maken een service, voegen een eindpunt voor elke binding toe, open de service en wacht totdat de gebruiker enter heeft bereikt voordat de service wordt gesloten.

Wanneer u de servicetesttoepassing start, ziet u de volgende uitvoer.

Testing Udp From Code.
Service is started from code...
Press <ENTER> to terminate the service and start service from config...

Vervolgens kunt u de testclienttoepassing uitvoeren op de gepubliceerde eindpunten. De clienttesttoepassing maakt een client voor elk eindpunt en verzendt vijf berichten naar elk eindpunt. De volgende uitvoer bevindt zich op de client.

Testing Udp From Imported Files Generated By SvcUtil.
0
3
6
9
12
Press <ENTER> to complete test.

Hier volgt de volledige uitvoer van de service.

Service is started from code...
Press <ENTER> to terminate the service and start service from config...
Hello, world!
Hello, world!
Hello, world!
Hello, world!
Hello, world!
   adding 0 + 0
   adding 1 + 2
   adding 2 + 4
   adding 3 + 6
   adding 4 + 8

Als u de clienttoepassing wilt uitvoeren op eindpunten die zijn gepubliceerd met behulp van de configuratie, drukt u op ENTER op de service en voert u de testclient opnieuw uit. U zou de volgende uitvoer op de service moeten zien.

Testing Udp From Config.
Service is started from config...
Press <ENTER> to terminate the service and exit...

Het uitvoeren van de client levert opnieuw hetzelfde resultaat op als de voorgaande resultaten.

Als u de clientcode en configuratie opnieuw wilt genereren met behulp van Svcutil.exe, start u de servicetoepassing en voert u vervolgens de volgende Svcutil.exe uit vanuit de hoofdmap van het voorbeeld.

svcutil http://localhost:8000/udpsample/ /reference:UdpTransport\bin\UdpTransport.dll /svcutilConfig:svcutil.exe.config

Houd er rekening mee dat Svcutil.exe de configuratie van de bindingsextensie voor de SampleProfileUdpBindingextensie niet genereert, dus u moet deze handmatig toevoegen.

<configuration>
  <system.serviceModel>
    <extensions>
      <!-- This was added manually because svcutil.exe does not add this extension to the file -->
      <bindingExtensions>
        <add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
      </bindingExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

Het voorbeeld instellen, compileren en uitvoeren

  1. Volg de instructies in Het bouwen van de Windows Communication Foundation-voorbeelden om de oplossing te bouwen.

  2. Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Windows Communication Foundation-voorbeelden uitvoeren.

  3. Raadpleeg de voorgaande sectie 'De UDP-testservice en -client'.