Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El ejemplo de transporte UDP muestra cómo implementar la unidifusión y multidifusión de UDP como un transporte de Windows Communication Foundation (WCF) personalizado. En el ejemplo se describe el procedimiento recomendado para crear un transporte personalizado en WCF, mediante el marco de canal y siguiendo los procedimientos recomendados de WCF. Los pasos para crear un transporte personalizado son los siguientes:
Decida cuál de los patrones de intercambio de mensajes del canal (IOutputChannel, IInputChannel, IDuplexChannel, IRequestChannel o IReplyChannel) admitirá ChannelFactory y ChannelListener. A continuación, decida si admitirá las variaciones con estado de sesión de estas interfaces.
Cree una fábrica de canales y un agente de escucha que admitan el patrón de intercambio de mensajes.
Asegúrese de que las excepciones específicas de la red se normalicen con la clase derivada adecuada de CommunicationException.
Agregue un <elemento de enlace> que agregue el transporte personalizado a una pila de canales. Para obtener más información, vea Agregar un elemento binding.
Agregue una sección de extensión de elemento de enlace para exponer el nuevo elemento de enlace al sistema de configuración.
Agregue extensiones de metadatos para comunicar funcionalidades a otros puntos de conexión.
Agregue un enlace que configure previamente una pila de elementos de enlace según un perfil bien definido. Para obtener más información, consulte Adición de una vinculación estándar.
Agregue una sección de enlace y un elemento de configuración de enlace para exponer el enlace al sistema de configuración. Para obtener más información, vea Añadir soporte de configuración.
Patrones de Intercambio de mensajes
El primer paso para escribir un transporte personalizado es decidir qué patrones de intercambio de mensajes (MEP) son necesarios para el transporte. Hay tres DIPUTADOs entre los que elegir:
Datagrama (IInputChannel/IOutputChannel)
Al utilizar un MEP de datagrama, un cliente envía un mensaje mediante un intercambio de tipo desencadenar y omitir. Un intercambio de este tipo es uno que exige una confirmación fuera de banda de entrega correcta. Es posible que el mensaje se pierda en tránsito y nunca llegue al servicio. Si la operación de envío se completa correctamente en el lado del cliente, no garantiza que el punto de conexión remoto haya recibido el mensaje. El datagrama es un bloque de creación fundamental para la mensajería, ya que puede crear sus propios protocolos sobre él, incluidos protocolos confiables y protocolos seguros. Los canales de datagrama de cliente implementan la interfaz IOutputChannel y los canales de datagrama de servicio implementan la interfaz IInputChannel.
Solicitud-respuesta (IRequestChannel/IReplyChannel)
En este MEP, se envía un mensaje y se recibe una respuesta. El patrón consta de pares de solicitud-respuesta. Algunos ejemplos de llamadas de solicitud-respuesta son llamadas a procedimientos remotos (RPC) y GET del explorador. Este patrón también se conoce como Half-Duplex. En este MEP, los canales de cliente implementan IRequestChannel y los canales de servicio implementan IReplyChannel.
Dúplex (IDuplexChannel)
El MEP dúplex permite que un cliente envíe un número arbitrario de mensajes y los reciba en cualquier orden. El MEP de dúplex es como una conversación telefónica, donde cada palabra que se pronuncia es un mensaje. Dado que ambos lados pueden enviar y recibir en este MEP, la interfaz implementada por los canales de cliente y servicio es IDuplexChannel.
Cada uno de estos eurodiputados también puede apoyar sesiones. La funcionalidad agregada proporcionada por un canal compatible con la sesión es que correlaciona todos los mensajes enviados y recibidos en un canal. El patrón Request-Response es una sesión independiente de dos mensajes, ya que la solicitud y la respuesta se correlacionan. Por el contrario, el patrón de solicitud-respuesta que admite las sesiones implica que se ponen en correlación todos los pares de solicitud/respuesta en ese canal entre sí. Esto le proporciona un total de seis MEPs (Datagram, Request-Response, Duplex, Datagram con sesiones, Request-Response con sesiones y Dúplex con sesiones) entre las que elegir.
Nota:
En el caso del transporte de UDP, el único MEP que se admite es el datagrama, ya que UDP es en sí mismo un protocolo de tipo "desencadenar y omitir".
El ICommunicationObject y el ciclo de vida del objeto WCF
WCF tiene una máquina de estado común que se usa para administrar el ciclo de vida de objetos como IChannel, IChannelFactoryy IChannelListener que se usan para la comunicación. Hay cinco estados en los que pueden existir estos objetos de comunicación. Estos estados se representan mediante la CommunicationState enumeración y son los siguientes:
Creado: este es el estado de un ICommunicationObject cuando se crea por primera vez. No se produce ninguna entrada/salida (E/S) en este estado.
Apertura: los objetos pasan a este estado cuando se llama a Open. En este punto, las propiedades se convierten en inmutables y la entrada y salida pueden comenzar. Esta transición solo es válida desde el estado Creado.
Abierto: los objetos pasan a este estado cuando se completa el proceso abierto. Esta transición solo es válida desde el estado Abriendo. En este punto, el objeto es totalmente utilizable para la transferencia.
Cerrando: los objetos pasan a este estado cuando se llama al método Close para que el apagado sea correcto. Esta transición solo es válida desde el estado Abierto.
Cerrado: en los objetos de estado Cerrado ya no se pueden usar. En general, la mayoría de las configuraciones siguen siendo accesibles para la inspección, pero no se puede producir ninguna comunicación. Este estado es equivalente a eliminarse.
Error: en el estado Defectuoso, los objetos son accesibles para la inspección, pero ya no se pueden usar. Cuando se produce un error no recuperable, el objeto pasa a este estado. La única transición válida desde este estado es al estado
Closed
.
Hay eventos que se desencadenan para cada transición de estado. El método Abort puede ser llamado en cualquier momento y hace que el objeto pase inmediatamente de su estado actual al estado Cerrado. La llamada a Abort termina cualquier trabajo pendiente.
Channel Factory y Channel Listener
El paso siguiente para escribir un transporte personalizado es crear una implementación de IChannelFactory para los canales de cliente y de IChannelListener para los canales de servicio. La capa de canal usa un patrón de generador para crear canales. WCF proporciona utilidades de clase base para este proceso.
La CommunicationObject clase implementa ICommunicationObject y aplica la máquina de estado descrita anteriormente en el paso 2.
La ChannelManagerBase clase implementa CommunicationObject y proporciona una clase base unificada para ChannelFactoryBase y ChannelListenerBase. La ChannelManagerBase clase funciona junto con ChannelBase, que es una clase base que implementa IChannel.
La ChannelFactoryBase clase implementa ChannelManagerBase y IChannelFactory consolida las
CreateChannel
sobrecargas en unOnCreateChannel
método abstracto.La ChannelListenerBase clase implementa IChannelListener. Se encarga de la administración básica del estado.
En este ejemplo, la implementación de fábrica se incluye en UdpChannelFactory.cs y la implementación del agente de escucha se encuentra en UdpChannelListener.cs. Las IChannel implementaciones están en UdpOutputChannel.cs y UdpInputChannel.cs.
Generador de canales UDP
UdpChannelFactory
deriva de ChannelFactoryBase. El ejemplo invalida GetProperty para proporcionar acceso a la versión del mensaje del codificador de mensajes. El ejemplo también invalida OnClose de manera que podamos anular nuestra instancia de BufferManager cuando se realizan las transiciones del equipo de estado.
Canal de salida UDP
La clase UdpOutputChannel
implementa la interfaz IOutputChannel. El constructor valida los argumentos y construye un objeto de destino EndPoint en función del objeto EndpointAddress que se pasa.
this.socket = new Socket(this.remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
El canal puede cerrarse de forma correcta o incorrecta. Si el canal se cierra correctamente, el socket se cierra y se realiza una llamada al método de clase OnClose
base. Si se inicia una excepción, la infraestructura llama a Abort
para garantizar que se limpia el canal.
this.socket.Close(0);
A continuación, implementamos Send()
y BeginSend()
/EndSend()
. Esto se divide en dos secciones principales. En primer lugar, serializamos el mensaje en una matriz de bytes.
ArraySegment<byte> messageBuffer = EncodeMessage(message);
A continuación, se envían los datos resultantes por la red.
this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count, SocketFlags.None, this.remoteEndPoint);
UdpChannelListener
El UdpChannelListener
que implementa el ejemplo deriva de la clase ChannelListenerBase. Usa un único socket UDP para recibir datagramas. El OnOpen
método recibe datos mediante el socket UDP en un bucle asincrónico. A continuación, los datos se convierten en mensajes mediante el marco de codificación de mensajes.
message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);
Dado que el mismo canal del datagrama representa mensajes que llegan de varios orígenes, UdpChannelListener
es un agente de escucha singleton. Hay, como máximo, un IChannel activo asociado con este oyente a la vez. El ejemplo genera otro solo si un canal devuelto por el método AcceptChannel
se elimina posteriormente. Cuando se recibe un mensaje, se pone en cola en este canal singleton.
UdpInputChannel
La UdpInputChannel
clase implementa IInputChannel
. Está compuesto de una cola de mensajes entrantes que es rellenada por el socket UdpChannelListener
. Estos mensajes se quitan de la cola mediante el método IInputChannel.Receive
.
Agregar un elemento de vinculación
Ahora que se construyen las fábricas y canales, debemos exponerlos al entorno de ejecución de ServiceModel a través de una vinculación. Un enlace es una colección de elementos de enlace que representa la pila de comunicación asociada con una dirección de servicio. Cada elemento de la pila se representa mediante un <elemento de enlace> .
En el ejemplo, el elemento de enlace es UdpTransportBindingElement
, que deriva de TransportBindingElement. Invalida los métodos siguientes para crear los generadores asociados con el enlace.
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);
}
También contiene los miembros para clonar BindingElement
y devolver nuestro esquema (soap.udp).
Agregación de compatibilidad con metadatos para un elemento de enlace de transporte
Para integrar nuestro transporte en el sistema de metadatos, debemos admitir tanto la importación como la exportación de políticas. Esto nos permite generar clientes de nuestra vinculación a través de la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe).
Adición de compatibilidad con WSDL
El elemento de transporte de una vinculación es responsable de exportar e importar información de direccionamiento en los metadatos. Al usar un enlace SOAP, el elemento de enlace de transporte también debe exportar un URI de transporte correcto en los metadatos.
Exportación de WSDL
Para exportar la información de direccionamiento, UdpTransportBindingElement
implementa la IWsdlExportExtension
interfaz . El ExportEndpoint
método agrega la información de direccionamiento correcta al puerto WSDL.
if (context.WsdlPort != null)
{
AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}
La UdpTransportBindingElement
implementación del ExportEndpoint
método también exporta un URI de transporte cuando el punto de conexión usa un enlace SOAP.
WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}
Importación de WSDL
Para ampliar el sistema de importación de WSDL para controlar la importación de las direcciones, debemos agregar la siguiente configuración al archivo de configuración para Svcutil.exe tal como se muestra en el archivo Svcutil.exe.config.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Al ejecutar Svcutil.exe, hay dos opciones para que Svcutil.exe cargue las extensiones de importación de WSDL.
Para señalar el archivo de configuración para su uso con Svcutil.exe, use el archivo /SvcutilConfig:<archivo>.
Agregue la sección de configuración a Svcutil.exe.config en el mismo directorio que Svcutil.exe.
El UdpBindingElementImporter
tipo implementa la IWsdlImportExtension
interfaz . El ImportEndpoint
método importa la dirección desde el puerto WSDL.
BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
ImportAddress(context);
}
Adición de soporte para políticas
El elemento de enlace personalizado puede exportar aserciones de directiva en el enlace de WSDL para que un extremo de servicio exprese las funciones de ese elemento de enlace.
Exportación de políticas
El UdpTransportBindingElement
tipo implementa IPolicyExportExtension
para agregar compatibilidad con la directiva de exportación. Como resultado, System.ServiceModel.MetadataExporter
incluye UdpTransportBindingElement
en la generación de directiva para cualquier enlace que la incluya.
En IPolicyExportExtension.ExportPolicy
, agregamos una aserción para UDP y otra aserción si estamos en modo de multidifusión. Esto se debe a que el modo de multidifusión afecta a cómo se construye la pila de comunicaciones, y, por tanto, debe coordinarse entre ambos lados.
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));
}
Dado que los elementos de enlace de transporte personalizados son responsables de la administración del direccionamiento, la implementación IPolicyExportExtension
en el UdpTransportBindingElement
también debe administrar la exportación de las aserciones de directivas WS-Addressing adecuadas para indicar la versión de WS-Addressing que se está utilizando.
AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);
Importación de directivas
Para ampliar el sistema de importación de directivas, debemos agregar la siguiente configuración al archivo de configuración de Svcutil.exe como se muestra en el archivo Svcutil.exe.config.
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
A continuación, implementamos IPolicyImporterExtension
desde nuestra clase registrada (UdpBindingElementImporter
). En ImportPolicy()
, examinamos las aserciones en nuestro espacio de nombres y procesamos las que se encargan de la generación del transporte y de la comprobación de si es multidifusión. También debemos eliminar las aseveraciones que controlamos de la lista de aserciones vinculantes. De nuevo, al ejecutar Svcutil.exe, hay dos opciones para la integración:
Para señalar el archivo de configuración para su uso con Svcutil.exe, use el archivo /SvcutilConfig:<archivo>.
Agregue la sección de configuración a Svcutil.exe.config en el mismo directorio que Svcutil.exe.
Agregar una vinculación estándar
Nuestro elemento de enlace se puede usar de las dos maneras siguientes:
A través de un enlace personalizado: un enlace personalizado permite al usuario crear su propio enlace basado en un conjunto arbitrario de elementos de enlace.
Mediante un enlace proporcionado por el sistema que incluye nuestro elemento de enlace. WCF proporciona una serie de estos enlaces definidos por el sistema, como
BasicHttpBinding
,NetTcpBinding
yWsHttpBinding
. Cada uno de estos enlaces está asociado a un perfil bien definido.
El ejemplo implementa el enlace del perfil en SampleProfileUdpBinding
, que deriva de Binding.
SampleProfileUdpBinding
contiene hasta cuatro elementos de enlace dentro de él: UdpTransportBindingElement
, TextMessageEncodingBindingElement CompositeDuplexBindingElement
y 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();
}
Agregación de un importador de enlace estándar personalizado
Svcutil.exe y el tipo WsdlImporter
, por defecto, reconocen e importan enlaces definidos por el sistema. De lo contrario, el enlace se importa como una instancia CustomBinding
. Para permitir que Svcutil.exe y WsdlImporter
importen el SampleProfileUdpBinding
, el UdpBindingElementImporter
actúa también como un importador de enlaces estándar personalizado.
Un importador de enlaces estándar personalizado implementa el ImportEndpoint
método en la IWsdlImportExtension
interfaz para examinar la CustomBinding
instancia importada de metadatos para ver si podría haber sido generada por un enlace estándar específico.
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;
}
}
}
Por lo general, la implementación de un importador de enlaces estándar personalizado implica comprobar las propiedades de los elementos de enlace importados para comprobar que solo las propiedades que el enlace estándar podría haber establecido han cambiado y todas las demás propiedades son sus valores predeterminados. Una estrategia básica para implementar un importador de enlaces estándar es crear una instancia del enlace estándar, propagar las propiedades de los elementos de enlace a la instancia de enlace estándar que admite el enlace estándar y comparar los elementos de enlace del enlace estándar con los elementos de enlace importados.
Agregación de la compatibilidad de configuración
Para exponer nuestro transporte a través de la configuración, debemos implementar dos secciones de configuración. El primero es BindingElementExtensionElement
para UdpTransportBindingElement
. Esto es para que CustomBinding
las implementaciones puedan hacer referencia a nuestro elemento de enlace. El segundo es Configuration
para SampleProfileUdpBinding
.
Elemento de extensión de elemento de enlace
La sección UdpTransportElement
es un BindingElementExtensionElement
que expone UdpTransportBindingElement
al sistema de configuración. Con algunas sobreescrituras básicas, definimos el nombre de la sección de configuración, el tipo de elemento de enlace y la forma de crear dicho elemento. A continuación, podemos registrar nuestra sección de extensión en un archivo de configuración como se muestra en el código siguiente.
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
</extensions>
</system.serviceModel>
</configuration>
Se puede hacer referencia a la extensión desde enlaces personalizados para usar UDP como transporte.
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding configurationName="UdpCustomBinding">
<udpTransport/>
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
Sección de enlace
La sección SampleProfileUdpBindingCollectionElement
es un StandardBindingCollectionElement
que expone SampleProfileUdpBinding
al sistema de configuración. La mayor parte de la implementación se delega en el SampleProfileUdpBindingConfigurationElement
, que deriva de StandardBindingElement
.
SampleProfileUdpBindingConfigurationElement
tiene propiedades que corresponden a las propiedades de SampleProfileUdpBinding
, y funciones para mapear desde el enlace de ConfigurationElement
. Por último, sobrescriba el método OnApplyConfiguration
en nuestro SampleProfileUdpBinding
, como se muestra en el código de ejemplo siguiente.
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;
}
Para registrar este controlador con el sistema de configuración, agregamos la siguiente sección al archivo de configuración correspondiente.
<configuration>
<configSections>
<sectionGroup name="system.serviceModel">
<sectionGroup name="bindings">
<section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</sectionGroup>
</sectionGroup>
</configSections>
</configuration>
A continuación, se puede hacer referencia a ella desde la sección de configuración 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>
El servicio de prueba udp y el cliente
El código de prueba para usar este transporte de ejemplo está disponible en los directorios UdpTestService y UdpTestClient. El código de servicio consta de dos pruebas: una prueba configura enlaces y puntos de conexión del código y el otro lo hace a través de la configuración. Ambas pruebas utilizan dos extremos. Un punto de conexión usa el SampleUdpProfileBinding
con <reliableSession> establecido en true
. El otro punto de conexión usa un enlace personalizado con UdpTransportBindingElement
. Esto equivale a usar SampleUdpProfileBinding
con <reliableSession> establecido en false
. Ambas pruebas crean un servicio, agregan un punto de conexión para cada enlace, abren el servicio y, a continuación, esperan a que el usuario presione ENTRAR antes de cerrar el servicio.
Al iniciar la aplicación de prueba de servicio, debería ver la salida siguiente.
Testing Udp From Code.
Service is started from code...
Press <ENTER> to terminate the service and start service from config...
A continuación, puede ejecutar la aplicación cliente de prueba en los puntos de conexión publicados. La aplicación de prueba de cliente crea un cliente para cada punto de conexión y envía cinco mensajes a cada punto de conexión. La siguiente salida se encuentra en el cliente.
Testing Udp From Imported Files Generated By SvcUtil.
0
3
6
9
12
Press <ENTER> to complete test.
A continuación, se muestra el resultado completo en el servicio.
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
Para ejecutar la aplicación cliente en puntos de conexión publicados mediante la configuración, presione ENTRAR en el servicio y vuelva a ejecutar el cliente de prueba. Debería ver el siguiente resultado en el servicio.
Testing Udp From Config.
Service is started from config...
Press <ENTER> to terminate the service and exit...
La ejecución del cliente de nuevo produce lo mismo que los resultados anteriores.
Para volver a generar el código de cliente y la configuración mediante Svcutil.exe, inicie la aplicación de servicio y, a continuación, ejecute el siguiente Svcutil.exe desde el directorio raíz del ejemplo.
svcutil http://localhost:8000/udpsample/ /reference:UdpTransport\bin\UdpTransport.dll /svcutilConfig:svcutil.exe.config
Tenga en cuenta que Svcutil.exe no genera la configuración de extensión de enlace para SampleProfileUdpBinding
, por lo que debe agregarla 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>
Para configurar, compilar y ejecutar el ejemplo
Para compilar la solución, siga las instrucciones de Creación de ejemplos de Windows Communication Foundation.
Para ejecutar el ejemplo en una configuración de una máquina única o entre máquinas, siga las instrucciones de Ejecución de los ejemplos de Windows Communication Foundation.
Consulte la sección anterior "El servicio de pruebas UDP y el cliente".