Introducción a un cliente WCF

En esta sección se describe qué hacen las aplicaciones cliente, cómo configurar, crear y utilizar un cliente de Windows Communication Foundation (WCF), y cómo proteger las aplicaciones cliente.

Utilización de objetos cliente WCF

Una aplicación cliente es una aplicación administrada que utiliza un cliente WCF para comunicarse con otra aplicación. Para crear la aplicación cliente de un servicio WCF es necesario seguir los pasos siguientes:

  1. Obtenga la información del contrato de servicio, el enlace y la dirección del extremo del servicio.

  2. Cree un cliente WCF con dicha información.

  3. Llame a las operaciones.

  4. Cierre el objeto del cliente WCF.

Las siguientes secciones explican estos pasos y proporcionan una breve introducción a las siguientes cuestiones:

  • Control de errores

  • Configuración y protección de los clientes.

  • Creación de objetos de devolución de llamada para los servicios dúplex.

  • Llamada asincrónica a los servicios.

  • Llamada a los servicios mediante los canales cliente.

Obtención del contrato de servicios, los enlaces y las direcciones

En WCF, los servicios y clientes modelan los contratos utilizando los atributos, interfaces y métodos administrados. Para conectar con un servicio en una aplicación cliente, es necesario obtener la información del tipo de contrato de servicios. Normalmente, se obtiene la información del tipo para el contrato de servicio mediante la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe). La utilidad descarga los metadatos del servicio, los convierte en un archivo de código fuente administrado con el lenguaje elegido y crea un archivo de configuración de aplicación cliente que puede usarse para configurar el objeto de cliente WCF. Por ejemplo, si se crea un objeto de cliente WCF para invocar un MyCalculatorService, y se sabe que los metadatos de ese servicio están publicados en http://computerName/MyCalculatorService/Service.svc?wsdl, el siguiente ejemplo de código muestra cómo utilizar Svcutil.exe para obtener un archivo ClientCode.vb que contenga el contrato de servicios en código administrado.

svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/MyCalculatorService/Service.svc?wsdl  

Puede compilar este código de contrato en la aplicación cliente, o en otro ensamblado que la aplicación cliente puede utilizar para crear un objeto de cliente WCF. Puede utilizar el archivo de configuración y configurar el objeto de cliente para conectarse correctamente con el servicio.

Para obtener un ejemplo de este proceso, consulte Creación de un cliente. Para obtener información completa sobre los contratos, consulte Contratos.

Creación de un objeto de cliente de WCF

Un cliente WCF es un objeto local que representa un servicio WCF en un formulario que el cliente puede usar para comunicarse con el servicio remoto. Los tipos de cliente WCF implementan el contrato de servicio de destino, de modo que cuando cree uno y lo configure, puede usar el objeto cliente directamente para invocar operaciones de servicio. El tiempo de ejecución de WCF convierte las llamadas al método en mensajes, los envía al servicio, realiza escuchas para la respuesta, y devuelve esos valores al objeto de cliente WCF como valores devueltos o parámetros out o ref.

También pueden utilizarse los objetos de canal de cliente WCF para la conexión con los servicios y la utilización de los mismos. Para más información, consulte Arquitectura de cliente WCF.

Creación de un nuevo objeto WCF

Para mostrar la utilización de una clase ClientBase<TChannel>, supongamos que el siguiente contrato de servicio simple se ha generado a partir de una aplicación de servicio.

Nota

Si se utiliza Visual Studio para crear el cliente WCF, cuando se agrega una referencia de servicio al proyecto, los objetos se cargan automáticamente en el examinador de objetos.

[System.ServiceModel.ServiceContractAttribute(
  Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
    [System.ServiceModel.OperationContractAttribute(
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
      ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
    )]
    [System.ServiceModel.FaultContractAttribute(
      typeof(microsoft.wcf.documentation.SampleFault),
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
    )]
    string SampleMethod(string msg);
}

Si no utiliza Visual Studio, examine el código de contrato generado para encontrar el tipo que extiende ClientBase<TChannel> y la interfaz del contrato de servicio ISampleService. En este caso, ese tipo es similar al código siguiente:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{

    public SampleServiceClient()
    {
    }

    public SampleServiceClient(string endpointConfigurationName)
        :
            base(endpointConfigurationName)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, string remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(binding, remoteAddress)
    {
    }
    public string SampleMethod(string msg)
    {
        return base.Channel.SampleMethod(msg);
    }
}

Esta clase puede crearse como un objeto local, mediante uno de los constructores, configurarse y, a continuación, utilizarse para la conexión con un servicio del tipo ISampleService.

Se recomienda crear primero el objeto de cliente WCF, y, a continuación, utilizarlo y cerrarlo dentro de un único bloque try/catch. No use la instrucción using (Using en Visual Basic) porque puede enmascarar excepciones en determinados modos de error. Para más información, consulte las secciones siguientes, así como Uso de Close y Abort para liberar los recursos del cliente WCF.

Contratos, enlaces y direcciones

Para crear un objeto de cliente WCF, este debe configurarse. En concreto, debe disponer de un punto de conexión de servicio que poder utilizar. Un punto de conexión es la combinación de un contrato de servicio, un enlace y una dirección. (Para más información sobre los puntos de conexión, consulte Puntos de conexión: direcciones, enlaces y contratos) Normalmente, esta información se encuentra en el elemento <punto de conexión> de un archivo de configuración de la aplicación cliente, como el que genera la herramienta Svcutil.exe, y se carga automáticamente al crear el objeto de cliente. Ambos tipos de cliente WCF también tienen sobrecargas que permiten especificar esta información mediante programación.

Por ejemplo, un archivo de configuración generado para el ISampleService utilizado en los ejemplos anteriores, contiene la información de extremo siguiente.

<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
                name="WSHttpBinding_ISampleService">
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Este archivo de configuración especifica un punto de conexión de destino en el elemento <client>. Para más información sobre el uso de varios puntos de conexión de destino, consulte los constructores ClientBase<TChannel> o ChannelFactory<TChannel>.

Llamadas a operaciones

Una vez creado y configurado un objeto de cliente, cree un bloque try/catch, llame a las operaciones del mismo modo a como lo haría si el objeto fuese local, y cierre el objeto de cliente WCF. Cuando la aplicación cliente llama a la primera operación, WCF abre automáticamente el canal subyacente, que se cierra al reciclar el objeto. (De manera alternativa, también puede abrir y cerrar explícitamente el canal antes o después de llamar a otras operaciones).

Por ejemplo, si posee el siguiente contrato de servicio:

namespace Microsoft.ServiceModel.Samples  
{  
    using System;  
    using System.ServiceModel;  
  
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]  
    public interface ICalculator  
   {  
        [OperationContract]  
        double Add(double n1, double n2);  
        [OperationContract]  
        double Subtract(double n1, double n2);  
        [OperationContract]  
        double Multiply(double n1, double n2);  
        [OperationContract]  
        double Divide(double n1, double n2);  
    }  
}  
Namespace Microsoft.ServiceModel.Samples  
  
    Imports System  
    Imports System.ServiceModel  
  
    <ServiceContract(Namespace:= _  
    "http://Microsoft.ServiceModel.Samples")> _
   Public Interface ICalculator  
        <OperationContract> _
        Function Add(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Subtract(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Multiply(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
     Function Divide(n1 As Double, n2 As Double) As Double  
End Interface  

Puede llamar a las operaciones mediante la creación de un objeto de cliente WCF y la llamada a sus métodos, como muestra el ejemplo de código siguiente. La apertura, llamada y cierre del objeto de cliente WCF tiene lugar en un bloque try/catch único. Para más información, consulte Acceso a los servicios mediante un cliente WCF y Uso de Close y Abort para liberar los recursos del cliente WCF.

CalculatorClient wcfClient = new CalculatorClient();
try
{
    Console.WriteLine(wcfClient.Add(4, 6));
    wcfClient.Close();
}
catch (TimeoutException timeout)
{
    // Handle the timeout exception.
    wcfClient.Abort();
}
catch (CommunicationException commException)
{
    // Handle the communication exception.
    wcfClient.Abort();
}

Control de errores

Las excepciones pueden producirse en una aplicación cliente cuando se abre el canal de cliente subyacente (explícita o automáticamente mediante la llamada a una operación), se utiliza el cliente u objeto de canal para llamar a las operaciones, o se cierra el canal de cliente subyacente. Se recomienda como mínimo que las aplicaciones prevean administrar posibles System.TimeoutException y las excepciones System.ServiceModel.CommunicationException, además de cualquier objeto System.ServiceModel.FaultException iniciado como resultado de los errores de SOAP devueltos por las operaciones. Los errores de SOAP especificados en el contrato de operación se elevan a las aplicaciones cliente como System.ServiceModel.FaultException<TDetail>, donde el parámetro de tipo es el tipo de detalle del error de SOAP. Para más información sobre el control de las condiciones de error en una aplicación cliente, consulte Envío y recepción de errores. Para obtener un ejemplo completo que muestre cómo controlar los errores en un cliente, consulte Excepciones esperadas.

Configuración y protección de clientes.

La configuración de un cliente se inicia con la carga de información de extremo de destino necesaria para el cliente u objeto de canal, normalmente desde un archivo de configuración, aunque también puede cargarse esta información mediante programación utilizando los constructores y propiedades de cliente. No obstante, son necesarios pasos de configuración adicionales que habiliten cierto comportamiento del cliente y diferentes escenarios de seguridad.

Por ejemplo, los requisitos de seguridad para los contratos de servicios se declaran en la interfaz del contrato de servicio; si Svcutil.exe creó un archivo de configuración, ese archivo contiene, normalmente, un enlace capaz de admitir los requisitos de seguridad del servicio. En algunos casos, sin embargo, puede ser necesaria una mayor configuración de seguridad, como la configuración de credenciales de cliente. Para obtener información completa sobre la configuración de seguridad para los clientes WCF, consulte Protección de clientes.

Además, algunas modificaciones personalizadas se pueden habilitar en aplicaciones cliente, como comportamientos en tiempo de ejecución personalizados. Para más información sobre la configuración de un comportamiento de cliente personalizado, consulte Configuración de los comportamientos del cliente.

Creación de objetos de devolución de llamada para servicios dúplex.

Los servicios dúplex especifican un contrato de devolución de llamada que la aplicación cliente debe implementar para proporcionar un objeto de devolución de llamada, y que el servicio realice las llamadas según los requisitos del contrato. Aunque los objetos de devolución de llamada no son servicios completos (por ejemplo, no puede iniciar un canal con un objeto de devolución de llamada), en lo que respecta la implementación y la configuración pueden concebirse como un tipo de servicio.

Los clientes de servicios dúplex deben:

  • Implementar una clase de contrato de devolución de llamada.

  • Crear una instancia de la clase de implementación de contrato de devolución de llamada, y utilizarla para crear el objeto System.ServiceModel.InstanceContext que se pasa al constructor de cliente WCF.

  • Invocar operaciones y controlar las devoluciones de llamada de la operación.

Los objetos de cliente WCF dúplex funcionan como sus homólogos no dúplex, salvo que exponen la funcionalidad necesaria para admitir las devoluciones de llamada, incluida la configuración del servicio de devolución de llamada.

Por ejemplo, pueden controlarse distintos aspectos del comportamiento del tiempo de ejecución del objeto de devolución de llamada mediante las propiedades del atributo System.ServiceModel.CallbackBehaviorAttribute, en la clase de devolución de llamada. Otro ejemplo es el uso de la clase System.ServiceModel.Description.CallbackDebugBehavior para habilitar el retorno de información de excepción a los servicios que llaman al objeto de devolución de llamada. Para obtener más información, consulte Servicios dúplex. Para obtener un ejemplo completo, consulte Dúplex.

En los equipos de Windows XP que ejecutan Internet Information Services (IIS) 5.1, los clientes dúplex deben especificar una dirección base de cliente utilizando la clase System.ServiceModel.WSDualHttpBinding, o se iniciará una excepción. En el ejemplo de código siguiente se muestra cómo realizar esta especificación en el código.

WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");

Dim dualBinding As New WSDualHttpBinding()
Dim endptadr As New EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server")
dualBinding.ClientBaseAddress = New Uri("http://localhost:8000/DuplexTestUsingCode/Client/")

El código siguiente muestra cómo realizar esta especificación en un archivo de configuración

<client>
  <endpoint
    name ="ServerEndpoint"
    address="http://localhost:12000/DuplexUsingConfig/Server"
    bindingConfiguration="WSDualHttpBinding_IDuplex"
    binding="wsDualHttpBinding"
    contract="IDuplex"
/>
</client>
<bindings>
  <wsDualHttpBinding>
    <binding
      name="WSDualHttpBinding_IDuplex"
      clientBaseAddress="http://localhost:8000/myClient/"
    />
  </wsDualHttpBinding>
</bindings>

Llamada a servicios de manera asincrónica.

La manera cómo se realizan las llamadas a las operaciones depende del desarrollador cliente. La razón es que los mensajes que constituyen una operación pueden asignarse a métodos sincrónicos o asincrónicos cuando se expresan en código administrado. Por consiguiente, si desea crear un cliente que llama a las operaciones de manera asincrónica, puede utilizar Svcutil.exe para generar código de cliente asincrónico mediante la opción /async. Para más información, consulte Procedimiento para llamar a operaciones de servicio WCF de forma asincrónica.

Llamada a los servicios mediante canales de cliente WCF.

Los tipos de cliente WCF extienden ClientBase<TChannel>, que, a su vez, deriva de la interfaz System.ServiceModel.IClientChannel para exponer el sistema del canal subyacente. Puede invocar los servicios utilizando el contrato de servicios de destino con la clase System.ServiceModel.ChannelFactory<TChannel>. Para más información, consulte Arquitectura de cliente WCF.

Consulte también