Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'esempio di trasporto UDP dimostra come implementare UDP unicast e multicast in quanto trasporto personalizzato di Windows Communication Foundation (WCF). Nell'esempio viene descritta la procedura consigliata per la creazione di un trasporto personalizzato in WCF, usando il framework del canale e seguendo le procedure consigliate per WCF. I passaggi per creare un trasporto personalizzato sono i seguenti:
Decidere quale dei modelli di scambio di messaggi del canale (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel o IReplyChannel) il ChannelFactory e il ChannelListener supporteranno. Decidere quindi se supportare le varianti con sessione di queste interfacce.
Creare una fabbrica di canali e un ascoltatore che supportino il modello di scambio di messaggi.
Assicurarsi che tutte le eccezioni specifiche della rete siano normalizzate per la classe derivata appropriata di CommunicationException.
Aggiungere un elemento di <binding> che aggiunge il trasporto personalizzato a una canalizzazione a strati. Per ulteriori informazioni, vedere Aggiunta di un elemento binding.
Aggiungere una sezione di estensione dell'elemento di associazione per esporre il nuovo elemento di associazione al sistema di configurazione.
Aggiungere estensioni di metadati per comunicare le funzionalità ad altri endpoint.
Aggiungere un'associazione che preconfigura uno stack di elementi di associazione in base a un profilo ben definito. Per altre informazioni, vedere Aggiunta di un'associazione standard.
Aggiungere una sezione di associazione e un elemento di configurazione dell'associazione per esporre l'associazione al sistema di configurazione. Per ulteriori informazioni, vedere Supporto alla configurazione.
Modelli di Scambio messaggi
Il primo passaggio per la scrittura di un trasporto personalizzato consiste nel decidere quali modelli di scambio messaggi (MEP) sono necessari per il trasporto. Ci sono tre deputati tra cui scegliere:
Datagramma (IInputChannel/IOutputChannel)
Quando si utilizza un MEP del datagramma, un client invia un messaggio tramite un meccanismo "fire and forget" (lancia e dimentica). Uno scambio di fuoco e di dimenticare è uno che richiede la conferma fuori banda della consegna con esito positivo. Il messaggio potrebbe essere perso in transito e non raggiungere mai il servizio. Se l'operazione di invio è completata con successo dal lato del client, ciò non garantisce che l'endpoint remoto abbia ricevuto il messaggio. Il datagramma è un blocco predefinito fondamentale per la messaggistica, in quanto è possibile creare protocolli personalizzati, inclusi protocolli affidabili e protocolli sicuri. I canali datagram client implementano l'interfaccia IOutputChannel e i canali datagram servizio implementano l'interfaccia IInputChannel.
Request-Response (IRequestChannel/IReplyChannel)
In questo MEP viene inviato un messaggio e viene ricevuta una risposta. Il modello è costituito da coppie request-response. Esempi di chiamate richiesta-risposta sono le chiamate RPC (Richieste di Procedura Remota) e le richieste GET del browser. Questo modello è noto anche come Half-Duplex. In questo MEP, i canali client implementano IRequestChannel e i canali del servizio implementano IReplyChannel.
Duplex (IDuplexChannel)
Il MEP duplex consente l'invio di un numero arbitrario di messaggi da parte di un client e ricevuti in qualsiasi ordine. Il MEP duplex è come una conversazione telefonica, in cui ogni parola pronunciata è un messaggio. Poiché entrambi i lati possono inviare e ricevere in questo MEP, l'interfaccia implementata dai canali client e di servizio è IDuplexChannel.
Ognuno di questi deputati può anche supportare sessioni. La funzionalità aggiunta fornita da un canale compatibile con la sessione è che correla tutti i messaggi inviati e ricevuti su un canale. Il modello Request-Response è una sessione a due messaggi autonoma, in quanto la richiesta e la risposta sono correlate. Al contrario, il modello di Request-Response che supporta le sessioni implica che tutte le coppie di richiesta/risposta su tale canale sono correlate tra loro. In questo modo è possibile ottenere un totale di sei MEP, ovvero Datagram, Request-Response, Duplex, Datagram con sessioni, Request-Response con sessioni e Duplex con sessioni, tra cui scegliere.
Annotazioni
Per il trasporto UDP, l'unico MEP supportato è Datagram, perché UDP è intrinsecamente un protocollo "fire and forget".
ICommunicationObject e il ciclo di vita degli oggetti WCF
WCF dispone di una macchina a stati comune usata per la gestione del ciclo di vita di oggetti come IChannel, IChannelFactorye IChannelListener usati per la comunicazione. Esistono cinque stati in cui questi oggetti di comunicazione possono esistere. Questi stati sono rappresentati dall'enumerazione CommunicationState e sono i seguenti:
Creato: questo è lo stato di un oggetto ICommunicationObject quando viene istanziato per la prima volta. In questo stato non si verifica alcun input/output (I/O).
Apertura: gli oggetti passano a questo stato quando Open viene chiamato . A questo punto le proprietà sono rese non modificabili e l'input/output può iniziare. Questa transizione è valida solo dallo stato Creato.
Aperto: gli oggetti passano a questo stato al termine del processo aperto. Questa transizione è valida solo dallo stato Di apertura. A questo punto, l'oggetto è completamente utilizzabile per il trasferimento.
Chiusura: Gli oggetti passano a questo stato quando Close viene chiamato per un arresto graduale. Questa transizione è valida solo dallo stato Aperto.
Chiuso: nello stato Chiuso gli oggetti non sono più utilizzabili. In generale, la maggior parte della configurazione è ancora accessibile per l'ispezione, ma non può verificarsi alcuna comunicazione. Questo stato equivale a essere eliminato.
Errore: nello stato Faulted gli oggetti sono accessibili per l'ispezione, ma non sono più utilizzabili. Quando si verifica un errore non ripristinabile, l'oggetto passa a questo stato. L'unica transizione valida da questo stato è nello
Closedstato .
Esistono eventi che vengono attivati per ogni transizione di stato. Il Abort metodo può essere chiamato in qualsiasi momento e fa sì che l'oggetto passi immediatamente dallo stato corrente allo stato Closed. La chiamata Abort termina qualsiasi lavoro non terminato.
Channel Factory e Channel Listener
Il passaggio successivo nella scrittura di un trasporto personalizzato consiste nel creare un'implementazione di IChannelFactory per i canali client e di IChannelListener per i canali servizio. Il livello del canale usa un modello factory per la costruzione di canali. WCF fornisce helper della classe di base per questo processo.
La classe CommunicationObject implementa ICommunicationObject e impone la macchina a stati precedentemente descritta nel passaggio 2.
La ChannelManagerBase classe implementa CommunicationObject e fornisce una classe base unificata per ChannelFactoryBase e ChannelListenerBase. La ChannelManagerBase classe funziona insieme a ChannelBase, che è una classe di base che implementa IChannel.
La ChannelFactoryBase classe implementa ChannelManagerBase e IChannelFactory e consolida i
CreateChannelsovraccarichi in un unicoOnCreateChannelmetodo astratto.La ChannelListenerBase classe implementa IChannelListener. Si occupa della gestione dello stato di base.
In questo esempio l'implementazione factory è contenuta in UdpChannelFactory.cs e l'implementazione del listener è contenuta in UdpChannelListener.cs. Le IChannel implementazioni si trovano in UdpOutputChannel.cs e UdpInputChannel.cs.
La Fabbrica di Canali UDP
Il UdpChannelFactory deriva da ChannelFactoryBase. L'esempio esegue l'override GetProperty per fornire l'accesso alla versione del messaggio del codificatore di messaggi. L'esempio sovrascrive anche OnClose in modo che sia possibile rimuovere l'istanza di BufferManager quando la macchina a stati effettua una transizione.
Canale di output UDP
Il UdpOutputChannel implementa IOutputChannel. Il costruttore convalida gli argomenti e costruisce un oggetto di destinazione EndPoint in base all'oggetto EndpointAddress passato.
this.socket = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
Il canale può essere chiuso normalmente o disgraziatamente. Se il canale viene chiuso normalmente, il socket viene chiuso e viene effettuata una chiamata al metodo della classe OnClose base. Se viene generata un'eccezione, l'infrastruttura chiama Abort per assicurarsi che il canale venga pulito.
this.socket.Close(0);
Implementiamo quindi Send() e BeginSend()/EndSend(). Questa operazione si suddivide in due sezioni principali. Prima di tutto, serializziamo il messaggio in una matrice di byte.
ArraySegment<byte> messageBuffer = EncodeMessage(message);
Quindi inviamo i dati risultanti sulla rete.
this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count, SocketFlags.None, this.remoteEndPoint);
The UdpChannelListener
L'oggetto UdpChannelListener che l'esempio implementa deriva dalla classe ChannelListenerBase. Usa un singolo socket UDP per ricevere datagrammi. Il OnOpen metodo riceve i dati usando il socket UDP in un ciclo asincrono. I dati vengono quindi convertiti in messaggi usando Message Encoding Framework.
message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);
Poiché lo stesso canale del datagramma rappresenta i messaggi che arrivano da una serie di origini, il listener è un singleton UdpChannelListener. Al massimo, può esserci un solo IChannel attivo associato a questo listener alla volta. L'esempio genera un altro solo se un canale restituito dal AcceptChannel metodo viene eliminato successivamente. Quando viene ricevuto un messaggio, viene accodato in questo canale unico.
UdpInputChannel
La UdpInputChannel classe implementa IInputChannel. È costituita da una coda di messaggi in arrivo popolata dal socket del UdpChannelListener. Questi messaggi vengono dequeuati dal IInputChannel.Receive metodo .
Aggiunta di un elemento di associazione
Ora che le factory e i canali sono costruiti, dobbiamo esporli al runtime di ServiceModel attraverso un binding. Un binding è una raccolta di elementi di binding che rappresenta lo stack di comunicazione associato a un indirizzo di servizio. Ogni elemento nello stack è rappresentato da un elemento di <associazione> .
Nell'esempio l'elemento di associazione è UdpTransportBindingElement, che deriva da TransportBindingElement. Esegue l'override dei metodi seguenti per compilare le factory associate all'associazione.
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);
}
Contiene anche membri per clonare BindingElement e restituire il nostro schema (soap.udp).
Aggiunta del supporto dei metadati per un elemento di associazione di trasporto
Per integrare il trasporto nel sistema di metadati, è necessario supportare sia l'importazione che l'esportazione dei criteri. In questo modo è possibile generare client del nostro binding tramite lo Strumento di Utilità Metadati ServiceModel (Svcutil.exe).
Aggiunta del supporto WSDL
L'elemento di associazione di trasporto in un'associazione è responsabile dell'esportazione e dell'importazione delle informazioni di indirizzamento nei metadati. Quando si usa un'associazione SOAP, l'elemento di associazione del trasporto deve esportare anche un URI di trasporto corretto nei metadati.
Esportazione WSDL
Per esportare le informazioni sull'indirizzamento, UdpTransportBindingElement implementa l'interfaccia IWsdlExportExtension . Il ExportEndpoint metodo aggiunge le informazioni di indirizzamento corrette alla porta WSDL.
if (context.WsdlPort != null)
{
AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}
L'implementazione UdpTransportBindingElement del ExportEndpoint metodo esporta anche un URI di trasporto quando l'endpoint usa un'associazione SOAP.
WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}
Importazione WSDL
Per estendere il sistema di importazione WSDL per gestire l'importazione degli indirizzi, è necessario aggiungere la configurazione seguente al file di configurazione per Svcutil.exe come illustrato nel file di Svcutil.exe.config.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Quando si esegue Svcutil.exe, sono disponibili due opzioni per ottenere Svcutil.exe per caricare le estensioni di importazione WSDL:
Indicare il punto Svcutil.exe nel file di configurazione utilizzando /SvcutilConfig:<file>.
Aggiungere la sezione di configurazione a Svcutil.exe.config nella stessa directory di Svcutil.exe.
Il UdpBindingElementImporter tipo implementa l'interfaccia IWsdlImportExtension . Il ImportEndpoint metodo importa l'indirizzo dalla porta WSDL.
BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
ImportAddress(context);
}
Aggiunta del supporto delle politiche
L'elemento di associazione personalizzato può esportare asserzioni di criteri nell'associazione WSDL per un endpoint di servizio per esprimere le funzionalità di tale elemento di associazione.
Esportazione dei criteri
Il UdpTransportBindingElement tipo implementa IPolicyExportExtension per aggiungere il supporto per l'esportazione delle politiche. Di conseguenza, System.ServiceModel.MetadataExporter include UdpTransportBindingElement nella generazione di criteri per qualsiasi associazione che lo include.
In IPolicyExportExtension.ExportPolicysi aggiunge un'asserzione per UDP e un'altra asserzione se si è in modalità multicast. Ciò è dovuto al fatto che la modalità multicast influisce sul modo in cui viene costruito lo stack di comunicazione e pertanto deve essere coordinata tra entrambi i lati.
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));
}
Poiché gli elementi personalizzati di associazione di trasporto sono responsabili della gestione dell'indirizzamento, l'implementazione di IPolicyExportExtension su UdpTransportBindingElement deve anche gestire l'esportazione delle appropriate asserzioni di criteri WS-Addressing per indicare la versione di WS-Addressing usata.
AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);
Importazione dei criteri
Per estendere il sistema di importazione dei criteri, è necessario aggiungere la configurazione seguente al file di configurazione per Svcutil.exe come illustrato nel file Svcutil.exe.config.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Quindi implementiamo IPolicyImporterExtension dalla nostra classe registrata (UdpBindingElementImporter). In ImportPolicy(), esaminiamo le asserzioni nello spazio dei nomi e processiamo quelle per generare il trasporto e verificare se è multicast. È anche necessario rimuovere le dichiarazioni gestite dall'elenco delle dichiarazioni vincolanti. Anche in questo caso, quando si esegue Svcutil.exe, sono disponibili due opzioni per l'integrazione:
Indicare il punto Svcutil.exe nel file di configurazione utilizzando /SvcutilConfig:<file>.
Aggiungere la sezione di configurazione a Svcutil.exe.config nella stessa directory di Svcutil.exe.
Aggiunta di un vincolo standard
L'elemento di associazione può essere usato nei due modi seguenti:
Tramite un'associazione personalizzata: un'associazione personalizzata consente all'utente di creare un'associazione personalizzata in base a un set arbitrario di elementi di associazione.
Usando un'associazione fornita dal sistema che include il nostro elemento di associazione. WCF fornisce una serie di queste associazioni definite dal sistema, ad esempio
BasicHttpBinding,NetTcpBindingeWsHttpBinding. Ognuna di queste associazioni è associata a un profilo ben definito.
L'esempio implementa l'associazione di profili in SampleProfileUdpBinding, che deriva da Binding.
SampleProfileUdpBinding Contiene fino a quattro elementi di associazione al suo interno: UdpTransportBindingElement, TextMessageEncodingBindingElement CompositeDuplexBindingElemente 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();
}
Aggiunta di un importatore di binding standard personalizzato
Svcutil.exe e il WsdlImporter tipo, per impostazione predefinita, riconosce e importa associazioni definite dal sistema. In caso contrario, il binding viene importato come istanza di CustomBinding. Per abilitare Svcutil.exe e l'oggetto WsdlImporter a importare SampleProfileUdpBinding, anche UdpBindingElementImporter funge da importatore di associazioni standard personalizzato.
Un'utilità di importazione di associazioni standard personalizzata implementa il ImportEndpoint metodo sull'interfaccia IWsdlImportExtension per esaminare l'istanza CustomBinding importata dai metadati per verificare se potrebbe essere stata generata da un'associazione standard specifica.
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;
}
}
}
In genere, l'implementazione di un'utilità di importazione dell'associazione standard personalizzata comporta la verifica delle proprietà degli elementi di associazione importati per verificare che solo le proprietà che potrebbero essere state impostate dall'associazione standard siano state modificate e che tutte le altre proprietà siano le relative impostazioni predefinite. Una strategia di base per l'implementazione di un'utilità di importazione dell'associazione standard consiste nel creare un'istanza dell'associazione standard, propagare le proprietà dagli elementi di associazione all'istanza di associazione standard supportata dall'associazione standard e confrontare gli elementi di associazione dall'associazione standard con gli elementi di associazione importati.
Aggiunta del supporto per la configurazione
Per esporre il nostro trasporto tramite la configurazione, è necessario implementare due sezioni di configurazione. Il primo è un BindingElementExtensionElement per UdpTransportBindingElement. In modo che le implementazioni CustomBinding possano fare riferimento all'elemento di associazione. Il secondo è un Configuration per il nostro SampleProfileUdpBinding.
Elemento di Estensione dell'Elemento di Composizione
La sezione UdpTransportElement è un oggetto BindingElementExtensionElement che espone UdpTransportBindingElement al sistema di configurazione. Con alcune sostituzioni di base, definiamo il nome della sezione di configurazione, il tipo dell'elemento di associazione e come creare l'elemento di associazione. È quindi possibile registrare la sezione dell'estensione in un file di configurazione, come illustrato nel codice seguente.
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
</extensions>
</system.serviceModel>
</configuration>
È possibile fare riferimento all'estensione nelle associazioni personalizzate per usare UDP come trasporto.
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding configurationName="UdpCustomBinding">
<udpTransport/>
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
Sezione Vincolante
La sezione SampleProfileUdpBindingCollectionElement è un oggetto StandardBindingCollectionElement che espone SampleProfileUdpBinding al sistema di configurazione. La maggior parte dell'implementazione viene delegata a SampleProfileUdpBindingConfigurationElement, che deriva da StandardBindingElement. l'oggetto SampleProfileUdpBindingConfigurationElement dispone di proprietà che corrispondono alle proprietà su SampleProfileUdpBinding, e funzioni per eseguire il mapping dall'associazione ConfigurationElement. Effettuare infine l'override del metodo OnApplyConfiguration nel nostro SampleProfileUdpBinding, come illustrato nel codice di esempio seguente.
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;
}
Per registrare questo gestore con il sistema di configurazione, aggiungere la sezione seguente al file di configurazione pertinente.
<configuration>
<configSections>
<sectionGroup name="system.serviceModel">
<sectionGroup name="bindings">
<section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</sectionGroup>
</sectionGroup>
</configSections>
</configuration>
È possibile farvi riferimento dalla sezione di configurazione 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>
Servizio di test UDP e client
Il codice di test per l'uso di questo trasporto di esempio è disponibile nelle directory UdpTestService e UdpTestClient. Il codice del servizio è costituito da due test: un test configura associazioni ed endpoint dal codice e l'altro lo esegue tramite la configurazione. Entrambi i test usano due endpoint. Un endpoint utilizza il SampleUdpProfileBinding con <reliableSession> impostato su true. L'altro endpoint usa un'associazione personalizzata con UdpTransportBindingElement. Equivale a usare SampleUdpProfileBinding con <reliableSession> impostato su false. Entrambi i test creano un servizio, aggiungono un endpoint per ogni associazione, aprono il servizio e quindi attendono che l'utente premi INVIO prima di chiudere il servizio.
Quando si avvia l'applicazione di test del servizio, verrà visualizzato l'output seguente.
Testing Udp From Code.
Service is started from code...
Press <ENTER> to terminate the service and start service from config...
È quindi possibile eseguire l'applicazione client di test sugli endpoint pubblicati. L'applicazione di test client crea un client per ogni endpoint e invia cinque messaggi a ogni endpoint. L'output seguente si trova nel client.
Testing Udp From Imported Files Generated By SvcUtil.
0
3
6
9
12
Press <ENTER> to complete test.
Di seguito è riportato l'output completo del servizio.
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
Per eseguire l'applicazione client sugli endpoint pubblicati usando la configurazione, premere INVIO nel servizio e quindi eseguire di nuovo il client di test. Nel servizio verrà visualizzato l'output seguente.
Testing Udp From Config.
Service is started from config...
Press <ENTER> to terminate the service and exit...
L'esecuzione del client restituisce di nuovo lo stesso risultato dei risultati precedenti.
Per rigenerare il codice client e la configurazione usando Svcutil.exe, avviare l'applicazione di servizio e quindi eseguire il seguente Svcutil.exe dalla directory radice dell'esempio.
svcutil http://localhost:8000/udpsample/ /reference:UdpTransport\bin\UdpTransport.dll /svcutilConfig:svcutil.exe.config
Si noti che Svcutil.exe non genera la configurazione dell'estensione di associazione per SampleProfileUdpBinding, quindi è necessario aggiungerla manualmente.
<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>
Per configurare, compilare ed eseguire l'esempio
Per compilare la soluzione, seguire le istruzioni riportate in Compilazione degli esempi di Windows Communication Foundation.
Per eseguire l'esempio in una configurazione con computer singolo o incrociato, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.
Fare riferimento alla sezione precedente "Servizio di test UDP e client".