Comparteix a través de


Acceso a los servicios utilizando un cliente

Para permitir la comunicación entre las aplicaciones cliente y los servicios, es necesario que se cree, configure y use el cliente de WCF u objetos de canal. En el tema Información general sobre el cliente de WCF, se proporciona información general sobre los pasos que deben seguirse y los objetos que se necesitan a la hora de crear un cliente básico y objetos de canal, así como sobre su uso.

Este tema proporciona información detallada sobre algunos de los problemas surgidos en las aplicaciones cliente y clientes y objetos de canal que pueden ser útiles en función de su escenario.

Información general

Este tema describe el comportamiento y problemas relacionados con:

  • Canal y duraciones de la sesión.

  • Control de excepciones

  • Entender los problemas que ocasionan el bloqueo.

  • Inicializar los canales interactivamente .

Duración de canales y sesiones

En las aplicaciones de Windows Communication Foundation (WCF), se incluyen dos categorías de canales: los canales de datagrama y los canales con sesión.

Un canal de datagrama es un canal en el que ninguno de los mensajes está correlacionado. Con un canal de datagrama, si una operación de entrada o de salida produce un error, normalmente la operación siguiente no estará afectada y se puede reutilizar el mismo canal. Por ello, normalmente, los canales de datagrama no producen errores.

Los canales con sesión, sin embargo, son canales en los que se establece una conexión al otro punto de conexión. Los mensajes de una sesión en un lado siempre están correlacionados con la misma sesión en el otro lado. Además, para que se considere correcta está sesión, ambos participantes de una sesión deben coincidir en que los requisitos de su conversación se han cumplido. Si no pueden coincidir, el canal con sesión puede producir un error.

Abra explícitamente o implícitamente los clientes llamando a la primera operación.

Nota

Generalmente, intentar detectar explícitamente los canales con sesión en los cuales se ha producido un error no es útil, porque cuando se notifica depende de la implementación de la sesión. Por ejemplo, dado que System.ServiceModel.NetTcpBinding (con la sesión de confianza deshabilitada) emerge la sesión de la conexión TCP, si escucha el evento ICommunicationObject.Faulted en el servicio o el cliente, probablemente, usted será notificado de forma rápida en caso de un error en la red. Pero las sesiones de confianza (establecidas por enlaces en los que System.ServiceModel.Channels.ReliableSessionBindingElement está habilitado) están diseñadas para aislar a los servicios de los errores de red pequeños. Si se puede restablecer la sesión dentro de un período razonable de tiempo, el mismo enlace, configurado para sesiones de confianza, no podría producir un error hasta que la interrupción continuara durante un período más largo de tiempo.

La mayoría de los enlaces proporcionados por el sistema (qué exponen canales al nivel de aplicación) utiliza sesiones de forma predeterminada, pero System.ServiceModel.BasicHttpBinding no. Para obtener más información, consulte Uso de sesiones.

El uso apropiado de sesiones

Las sesiones proporcionan una manera de conocer si todo el intercambio de mensajes ha finalizado, y si ambos lados lo consideraran correcto. Se recomienda que una aplicación que realiza la llamada abra el canal, lo utilice y cierre el canal dentro de un bloque try. Si un canal de sesión está abierto, y se llama al método ICommunicationObject.Close una vez y esa llamada se devuelve correctamente, a continuación, la sesión se ha completado correctamente. Correctamente en este caso significa que todas las garantías de entrega especificadas por el enlace se cumplieron y que el otro lado no llamó ICommunicationObject.Abort en el canal antes de llamar Close.

La sección siguiente proporciona un ejemplo de este enfoque del cliente.

Controlar las excepciones

Administrar las excepciones en las aplicaciones cliente es sencillo. Si se abre, se utiliza y se cierra un canal dentro de un bloque try, la conversación ha se ha completado correctamente, a menos que se produzca una excepción. En general, si se produce una excepción se anula la conversación.

Nota

El uso de la instrucción using (Using en Visual Basic) no es recomendable. Esto es debido a que el fin de la instrucción using puede producir excepciones que pueden enmascarar otras excepciones que usted pueden necesitar conocer. Para obtener más información, consulte Uso de Close y Abort para liberar los recursos del cliente WCF.

El ejemplo de código siguiente muestra el patrón del cliente recomendado mediante un try/bloque catch y no la instrucción using.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;

public class Client
{
  public static void Main()
  {
    // Picks up configuration from the config file.
    SampleServiceClient wcfClient = new SampleServiceClient();
    try
    {
      // Making calls.
      Console.WriteLine("Enter the greeting to send: ");
      string greeting = Console.ReadLine();
      Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));

      Console.WriteLine("Press ENTER to exit:");
      Console.ReadLine();

      // Done with service.
      wcfClient.Close();
      Console.WriteLine("Done!");
    }
    catch (TimeoutException timeProblem)
    {
      Console.WriteLine("The service operation timed out. " + timeProblem.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException<GreetingFault> greetingFault)
    {
      Console.WriteLine(greetingFault.Detail.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException unknownFault)
    {
      Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (CommunicationException commProblem)
    {
      Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
      Console.ReadLine();
      wcfClient.Abort();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation

Public Class Client
    Public Shared Sub Main()
        ' Picks up configuration from the config file.
        Dim wcfClient As New SampleServiceClient()
        Try
            ' Making calls.
            Console.WriteLine("Enter the greeting to send: ")
            Dim greeting As String = Console.ReadLine()
            Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))

            Console.WriteLine("Press ENTER to exit:")
            Console.ReadLine()

            ' Done with service. 
            wcfClient.Close()
            Console.WriteLine("Done!")
        Catch timeProblem As TimeoutException
            Console.WriteLine("The service operation timed out. " & timeProblem.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch greetingFault As FaultException(Of GreetingFault)
            Console.WriteLine(greetingFault.Detail.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch unknownFault As FaultException
            Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch commProblem As CommunicationException
            Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
            Console.ReadLine()
            wcfClient.Abort()
        End Try
    End Sub
End Class

Nota

Comprobar el valor de la propiedad ICommunicationObject.State es una condición de carrera y no se recomienda para determinar si reutilizar o cerrar un canal.

Los canales de datagrama nunca producen errores, incluso si se producen excepciones cuando se cierran. Además, los clientes no dúplex que no se autentican mediante una conversación segura, normalmente, inician System.ServiceModel.Security.MessageSecurityException. Sin embargo, si el cliente dúplex que utiliza una conversación segura no se autentica, el cliente recibe en su lugar System.TimeoutException.

Para obtener información más completa sobre el uso de la información de error en el nivel de aplicación, consulte Especificación y control de errores en contratos y servicios. En el artículo Excepciones esperadas, se describen las excepciones que se esperan y se muestra cómo controlarlas. Para obtener más información sobre cómo controlar los errores que suceden al desarrollar canales, consulte Control de excepciones y errores.

Bloqueo de clientes y rendimiento

Cuando una aplicación llama sincrónicamente a una operación de solicitud-respuesta, el cliente se bloquea hasta que se reciba un valor devuelto o se produzca una excepción (como un System.TimeoutException). Este comportamiento es similar al comportamiento local. Cuando se invoca sincrónicamente a una operación en un objeto o canal del cliente de WCF en una aplicación, el cliente no vuelve hasta que los datos se puedan escribir en la red desde la capa de canal o hasta que se inicie una excepción. Y mientras el patrón de intercambio de mensaje unidireccional (especificado marcando una operación con OperationContractAttribute.IsOneWay establecida en true) puede hacer que algunos clientes sean más receptivos, las operaciones unidireccionales también se pueden bloquear, dependiendo del enlace y de los mensajes que ya se han enviado. Las operaciones unidireccionales son solo sobre intercambio de mensajes, nada más y nada menos. Para obtener más información, consulte Servicios unidireccionales.

Los fragmentos de datos grandes pueden desacelerar el procesamiento del cliente, independientemente del patrón de intercambio de mensajes. Para comprender cómo pueden controlarse estos problemas, consulte Datos grandes y streaming.

Si deben realizarse otras tareas en la aplicación mientras se completa una operación, cree un par del métodos asincrónico en la interfaz del contrato de servicio que ha implementado en su cliente de WCF. La manera más fácil de hacerlo consiste en usar el modificador /async de la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe). Para obtener un ejemplo completo, consulte Procedimiento para llamar a operaciones de servicio WCF de forma asincrónica.

Para obtener más información sobre cómo aumentar el rendimiento del cliente, consulte Aplicaciones cliente de nivel intermedio.

Permitir que el usuario seleccione credenciales dinámicamente

La interfaz IInteractiveChannelInitializer permite a las aplicaciones mostrar una interfaz de usuario que permite al usuario elegir credenciales con las que crear un canal antes del inicio de los temporizadores de tiempo de espera.

Hay dos maneras con las que los desarrolladores de aplicaciones pueden hacer uso de un IInteractiveChannelInitializer insertado. Desde la aplicación cliente, puede llamarse a los métodos ClientBase<TChannel>.DisplayInitializationUI o IClientChannel.DisplayInitializationUI (o a una versión asincrónica de estos) antes de que se abra el canal (esto sería un enfoque explícito) o, simplemente, llamar a la primera operación (un enfoque implícito).

Si se utiliza el enfoque implícito, la aplicación debe llamar a la primera operación en una extensión de ClientBase<TChannel> o IClientChannel. Si no llama a la primera operación, se inicia una excepción.

Si se utiliza el enfoque explícito, la aplicación debe realizar los pasos siguientes en orden:

  1. Llamar a ClientBase<TChannel>.DisplayInitializationUI o a IClientChannel.DisplayInitializationUI (o una versión asincrónica).

  2. Cuando se hayan devuelto los inicializadores, llamar al método Open en el objeto IClientChannel o en el objeto IClientChannel devuelto de la propiedad ClientBase<TChannel>.InnerChannel.

  3. Llame a las operaciones.

Se recomienda que las aplicaciones de calidad de producción controlen el proceso de la interfaz del usuario mediante el enfoque explícito.

Las aplicaciones que utilizan el enfoque implícito invocan los inicializadores de la interfaz de usuario, pero si el usuario de la aplicación no responde dentro del plazo de tiempo de espera de envío del enlace, se inicia una excepción cuando se devuelve la interfaz de usuario.

Consulte también