Accès aux services à l'aide d'un client

Les applications clientes doivent créer, configurer et utiliser des objets client ou canal WCF pour communiquer avec les services. La rubrique Vue d’ensemble du client WCF fournit une vue d'ensemble des objets et des étapes nécessaires pour créer des objets de client et de canal de base, ainsi que des informations sur leur utilisation.

Cette rubrique fournit des informations détaillées sur certains aspects liés aux applications clientes et aux objets de client et de canal qui peuvent être utiles selon votre scénario.

Vue d’ensemble

Cette rubrique décrit le comportement et les problèmes liés aux éléments suivants :

  • durées de vie de session et de canal ;

  • gestion des exceptions ;

  • présentation des problèmes de blocage ;

  • initialisation de canaux de manière interactive.

Durées de vie de session et de canal

Les applications Windows Communication Foundation (WCF) incluent deux catégories de canaux : les canaux de datagramme et les canaux de session.

Un canal de datagramme est un canal dans lequel tous les messages sont sans corrélation. Avec un canal de datagramme, si une opération d'entrée ou de sortie échoue, l'opération suivante n'est en général pas affectée et le même canal peut être réutilisé. Pour cette raison, les canaux de datagramme ne subissent généralement pas de défaillance.

Toutefois, les canaux avec session sont des canaux avec une connexion à l’autre point de terminaison. Les messages dans une session d'un côté sont toujours en corrélation avec la même session de l'autre côté. De plus, les deux participants d'une session doivent s'entendre sur le fait que les spécifications de leur conversation ont été satisfaites pour que cette session soit considérée comme réussie. S'ils ne peuvent se mettre d'accord, le canal de session peut subir une défaillance.

Ouvrir des clients explicitement ou implicitement en appelant la première opération.

Notes

Le fait de tenter de détecter de manière explicite des canaux de session défaillants est en général inutile, car le moment où vous en êtes informé dépend de l'implémentation de session. Par exemple, étant donné que le System.ServiceModel.NetTcpBinding (avec la session fiable désactivée) est à la surface de la session de la connexion TCP, si vous écoutez l'événement ICommunicationObject.Faulted sur le service ou le client, vous recevrez sans doute rapidement une notification en cas de panne réseau. Mais les sessions fiables (établies par des liaisons dans lesquelles le System.ServiceModel.Channels.ReliableSessionBindingElement est activé) sont conçues pour isoler les services des petites pannes réseau. Si la session peut être rétablie dans un délai raisonnable, la même liaison (configuré pour des sessions fiables) risque de ne subir une défaillance que longtemps après l'interruption.

La plupart des liaisons fournies par le système (qui exposent des canaux à la couche Application) utilisent des sessions par défaut, ce qui n'est pas le cas du System.ServiceModel.BasicHttpBinding. Pour plus d’informations, consultez Utilisation de sessions.

Utilisation correcte des sessions

Les sessions offrent un moyen de savoir si l'intégralité de l'échange de messages a été effectué et si les deux côtés l'ont considéré réussi. Il est recommandé qu'une application appelante ouvre le canal, l'utilise et le ferme à l'intérieur d'un bloc try. Si un canal de session est ouvert, que la méthode ICommunicationObject.Close est appelée une fois et que cet appel est retourné avec succès, cela signifie que la session a réussi. Le terme « réussi » dans ce cas signifie que toutes les garanties de remise spécifiées par la liaison ont été satisfaites et que l'autre côté n'a pas appelé ICommunicationObject.Abort sur le canal avant d'appeler Close.

La section suivante fournit un exemple de cette approche cliente.

Gestion des exceptions

La gestion des exceptions dans les applications clientes est simple. Si un canal est ouvert, utilisé et fermé à l'intérieur d'un bloc try, cela signifie que la conversation a réussi, à moins qu'une exception ne soit levée. En général, si une exception est levée, la conversation est abandonnée.

Notes

L’utilisation de l’instruction using (Using en Visual Basic) n’est pas recommandée. Cela est dû au fait que la fin de l'instruction using peut provoquer des exceptions qui peuvent masquer d'autres exceptions dont vous devez avoir connaissance. Pour plus d’informations, consultez Utiliser Fermer et abandonner pour libérer les ressources clientes WCF.

L'exemple de code suivant illustre le modèle client recommandé à l'aide d'un bloc try/catch, et non de l'instruction 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

Notes

La vérification de la valeur de la propriété ICommunicationObject.State est une condition de concurrence et n'est pas recommandée pour déterminer s'il faut réutiliser ou fermer un canal.

Les canaux de datagramme ne subissent jamais de défaillance, même si des exceptions se produisent lorsqu'ils sont fermés. De plus, les clients non-duplex qui ne parviennent pas à s'authentifier à l'aide d'une conversation sécurisée lèvent en général une exception System.ServiceModel.Security.MessageSecurityException. Toutefois, si le client duplex qui utilise une conversation sécurisée ne parvient pas à s'authentifier, il reçoit une exception System.TimeoutException.

Pour plus d’informations sur l’utilisation des informations d’erreur au niveau de l’application, consultez Spécification et gestion des erreurs dans les contrats et les services. Exceptions attendues décrit les exceptions attendues et montre comment les gérer. Pour plus d’informations sur la gestion des erreurs lors du développement de canaux, consultez Gestion des exceptions et des erreurs.

Blocage de client et performances

Lorsqu'une application appelle une opération demande-réponse de façon synchrone, le client se bloque jusqu'à ce qu'une valeur de retour soit reçue ou qu'une exception (par exemple System.TimeoutException) soit levée. Ce comportement est semblable au comportement local. Lorsqu’une application appelle de façon synchrone une opération sur un objet ou un canal de client WCF, le client n’est retourné que lorsque la couche de canal peut écrire les données sur le réseau ou lorsqu’une exception est levée. Et bien que le modèle d’échange de messages unidirectionnel (spécifié en marquant une opération avec OperationContractAttribute.IsOneWay défini à true) puisse améliorer la capacité de réponse de certains clients, les opérations unidirectionnelles peuvent également subir un blocage, en fonction de la liaison et des messages qui ont déjà été envoyés. Les opérations unidirectionnelles concernent uniquement l'échange de messages, ni plus ni moins. Pour plus d’informations, consultez Services unidirectionnels.

Les grands segments de données peuvent ralentir le traitement client, quel que soit le modèle d’échange de messages. Pour comprendre comment gérer ces problèmes, consultez Données volumineuses et diffusion en continu.

Si votre application doit effectuer davantage de travail pendant qu’une opération se termine, vous devez créer une paire de méthodes asynchrone sur l’interface de contrat de service que votre client WCF implémente. La façon la plus simple de le faire est d’utiliser la bascule /async sur l’Outil ServiceModel Metadata Utility (Svcutil.exe). Pour obtenir un exemple, consultez Comment : Appeler des opérations de service de manière asynchrone.

Pour plus d’informations sur l’augmentation des performances des clients, consultez Applications clientes de niveau intermédiaire.

Autoriser l'utilisateur à sélectionner des informations d'identification de manière dynamique

L'interface IInteractiveChannelInitializer permet aux applications d'afficher une interface utilisateur qui permet à l'utilisateur de choisir des informations d'identification avec lesquelles un canal est créé avant le démarrage des minuteries de délai d'attente.

Les développeurs d'applications peuvent utiliser un IInteractiveChannelInitializer inséré de deux façons. L’application cliente peut appeler ClientBase<TChannel>.DisplayInitializationUI ou IClientChannel.DisplayInitializationUI (ou une version asynchrone) avant d’ouvrir le canal (approche explicite ) ou appeler la première opération (l’approche implicite ).

Lors de l’utilisation de l’approche implicite, l’application doit appeler la première opération sur une extension ClientBase<TChannel> ou IClientChannel. Si elle appelle une autre opération que la première, une exception est levée.

Lors de l'utilisation de l'approche explicite, l'application doit exécuter les étapes suivantes, dans l'ordre :

  1. Appelez ClientBase<TChannel>.DisplayInitializationUI ou IClientChannel.DisplayInitializationUI (ou une version asynchrone).

  2. Lorsque les initialiseurs ont retourné, appelez la méthode Open sur l'objet IClientChannel ou sur l'objet IClientChannel retourné par la propriété ClientBase<TChannel>.InnerChannel.

  3. Appelez les opérations.

Il est recommandé que les applications de qualité de production contrôlent le processus d'interface utilisateur en adoptant l'approche explicite.

Les applications qui utilisent l'approche implicite appellent les initialiseurs d'interface utilisateur, mais si l'utilisateur de l'application ne répond pas avant la fin du délai d'attente d'envoi de la liaison, une exception est levée lorsque l'interface utilisateur retourne.

Voir aussi