Transport: UDP
Het UDP Transport-voorbeeld laat zien hoe u UDP unicast en multicast implementeert als een aangepast WCF-transport (Windows Communication Foundation). In het voorbeeld wordt de aanbevolen procedure beschreven voor het maken van een aangepast transport in WCF, met behulp van het kanaalframework en de volgende WCF-best practices. De stappen voor het maken van een aangepast transport zijn als volgt:
Bepaal welke van de kanaal Message Exchange Patterns (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel of IReplyChannel) uw ChannelFactory en ChannelListener worden ondersteund. Bepaal vervolgens of u de sessievolle variaties van deze interfaces wilt ondersteunen.
Maak een kanaalfactory en listener die ondersteuning bieden voor uw Message Exchange-patroon.
Zorg ervoor dat eventuele netwerkspecifieke uitzonderingen worden genormaliseerd naar de juiste afgeleide klasse van CommunicationException.
Voeg een <bindingselement> toe waarmee het aangepaste transport wordt toegevoegd aan een kanaalstack. Zie Een bindingselement toevoegen voor meer informatie.
Voeg een sectie voor de extensie voor bindingselementen toe om het nieuwe bindingselement beschikbaar te maken voor het configuratiesysteem.
Voeg metagegevensextensies toe om mogelijkheden te communiceren met andere eindpunten.
Voeg een binding toe waarmee een stapel bindingselementen vooraf wordt geconfigureerd volgens een goed gedefinieerd profiel. Zie Een standaardbinding toevoegen voor meer informatie.
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 om te bepalen welke Message Exchange Patterns (EP-leden) 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 brand en vergeet uitwisseling is een die 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 datagram kanalen implementeren de IOutputChannel interface en service datagram kanalen 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 IRequestChannel en servicekanalen clientkanalen implementeren 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 beide zijden in dit MEP kunnen verzenden en ontvangen, is de interface die door de client- en servicekanalen wordt IDuplexChannelgeïmplementeerd.
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 patroon Aanvraag-antwoord is een zelfstandige sessie met twee berichten, omdat de aanvraag en het antwoord gecorreleerd zijn. Het patroon Aanvraag-antwoord dat sessies ondersteunt, houdt daarentegen in dat alle aanvraag-/antwoordparen op dat kanaal met elkaar zijn gecorreleerd. Dit geeft u in totaal zes LEDEN: Datagram, Request-Response, Duplex, Datagram met sessies, Request-Response met sessies en Duplex met sessies, waaruit u kunt kiezen.
Notitie
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 status wanneer Open deze 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 statusobjecten zijn 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 worden geactiveerd voor 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 clientkanalen en IChannelListener servicekanalen. De kanaallaag maakt gebruik van een fabriekspatroon voor het maken van kanalen. WCF biedt basisklasse-helpers voor dit proces.
De CommunicationObject klasse implementeert en dwingt ICommunicationObject de statusmachine af die eerder is beschreven in stap 2.
De ChannelManagerBase klasse implementeert CommunicationObject en biedt een uniforme basisklasse voor ChannelFactoryBase en ChannelListenerBase. De ChannelManagerBase klasse werkt in combinatie met ChannelBase, een basisklasse die wordt geïmplementeerd IChannel.
De ChannelFactoryBase klasse implementeert ChannelManagerBase en IChannelFactory consolideert de
CreateChannel
overbelastingen in éénOnCreateChannel
abstracte methode.De ChannelListenerBase klasse implementeert IChannelListener. Het zorgt voor basisstatusbeheer.
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-kanaalfactory
De UdpChannelFactory
afgeleiden van ChannelFactoryBase. Het voorbeeld overschrijft GetProperty om toegang te bieden tot de berichtversie van de berichtcoderingsprogramma. Het voorbeeld overschrijft OnClose ook zodat we ons exemplaar kunnen afbreken wanneer BufferManager de statusmachine overgaat.
Het UDP-uitvoerkanaal
De UdpOutputChannel
implementaties 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 correct of geforceerd worden gesloten. Als het kanaal correct is gesloten, wordt de socket gesloten en wordt er een aanroep uitgevoerd naar de basisklassemethode OnClose
. 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
voorbeeld 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 nog een kanaal als een kanaal dat door de AcceptChannel
methode wordt geretourneerd, vervolgens wordt verwijderd. Wanneer een bericht wordt ontvangen, wordt het in dit singleton-kanaal geplaatst.
UdpInputChannel
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 in de wachtrij geplaatst.
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 UdpTransportBindingElement
het bindingselement , dat is afgeleid van TransportBindingElement. Het overschrijft de volgende methoden om de factory's 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 retourneren 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 UdpTransportBindingElement
IWsdlExportExtension
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 bestand Svcutil.exe.config.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Wanneer u Svcutil.exe uitvoert, zijn er twee opties om Svcutil.exe te krijgen om de WSDL-importextensies te laden:
Wijs Svcutil.exe naar ons configuratiebestand met behulp van het bestand> /SvcutilConfig:<.
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 System.ServiceModel.MetadataExporter
omvat u UdpTransportBindingElement
het genereren van beleid voor elke binding die deze bevat.
In IPolicyExportExtension.ExportPolicy
voegen 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
implementatie ook de juiste WS-Adresseringsbeleidsverklaringen verwerken om aan te geven welke versie van WS-Adressering 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 en verwerken we de asserties voor het genereren van het transport en controleren we of het multicast is. We moeten ook de asserties verwijderen die we verwerken uit de lijst met bindingsverklaringen. Ook bij het uitvoeren van Svcutil.exe zijn er twee opties voor integratie:
Wijs Svcutil.exe naar ons configuratiebestand met behulp van het bestand> /SvcutilConfig:<.
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
,NetTcpBinding
enWsHttpBinding
. Elk van deze bindingen is gekoppeld aan een goed gedefinieerd profiel.
In het voorbeeld wordt profielbinding geïmplementeerd SampleProfileUdpBinding
, die is afgeleid van Binding. De SampleProfileUdpBinding
bevat maximaal vier bindingselementen erin: UdpTransportBindingElement
, TextMessageEncodingBindingElement CompositeDuplexBindingElement
en 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
Svcutil.exe en het type worden standaard door het WsdlImporter
systeem gedefinieerde bindingen herkend en geïmporteerd. Anders wordt de binding geïmporteerd als een CustomBinding
exemplaar. Om Svcutil.exe en de WsdlImporter
importfunctie in te schakelen, fungeert de UdpBindingElementImporter
SampleProfileUdpBinding
functie ook als een aangepaste standaardbindingsimporteur.
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 ons SampleProfileUdpBinding
.
ElementExtensie voor bindingselement
De sectie is een BindingElementExtensionElement
sectie UdpTransportElement
die beschikbaar is voor UdpTransportBindingElement
het configuratiesysteem. Met enkele eenvoudige onderdrukkingen definiëren we de naam van de configuratiesectie, het type bindingelement en het maken van ons bindingselement. 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>
Bindingssectie
De sectie is een StandardBindingCollectionElement
sectie SampleProfileUdpBindingCollectionElement
die beschikbaar is voor SampleProfileUdpBinding
het configuratiesysteem. Het grootste deel van de implementatie wordt gedelegeerd aan de SampleProfileUdpBindingConfigurationElement
, die is afgeleid van StandardBindingElement
. De SampleProfileUdpBindingConfigurationElement
eigenschappen komen overeen met de eigenschappen op SampleProfileUdpBinding
en functies die vanuit de ConfigurationElement
binding moeten worden toegewezen. 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 -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 gelijk aan het gebruik met SampleUdpProfileBinding
<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 ziet nu de volgende uitvoer van de service.
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 SampleProfileUdpBinding
extensie niet genereert, dus moet u 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
Volg de instructies in Het bouwen van de Windows Communication Foundation-voorbeelden om de oplossing te bouwen.
Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.
Raadpleeg de voorgaande sectie 'De UDP-testservice en -client'.