Développement client à l’aide de handles de contexte

La seule utilisation d’un programme client pour un handle de contexte consiste à le transmettre au serveur chaque fois que le client effectue un appel de procédure distante. L’application cliente n’a pas besoin d’accéder au contenu du handle. Il ne doit pas essayer de modifier le contexte de gérer les données de quelque manière que ce soit. Les procédures distantes appelées par le client effectuent toutes les opérations nécessaires sur le contexte du serveur.

Avant de demander un handle de contexte à partir d’un serveur, les clients doivent établir une liaison avec le serveur. Le client peut utiliser un handle de liaison automatique, implicite ou explicite. Avec un handle de liaison valide, le client peut appeler une procédure distante sur le serveur qui retourne un handle de contexte ouvert (non NULL) ou en transmet un via un paramètre [out] dans la liste de paramètres de la procédure distante.

Les clients peuvent utiliser des handles de contexte ouverts de toute façon dont ils ont besoin. Toutefois, ils doivent invalider le handle lorsqu’ils n’en ont plus besoin. Il existe deux façons de procéder :

  • Pour appeler une procédure distante proposée par le programme serveur qui libère le contexte et ferme le handle de contexte (définit-le sur NULL).
  • Lorsque le serveur est inaccessible, appelez la fonction RpcSsDestroyClientContext .

La deuxième approche nettoie uniquement l’état côté client et ne nettoie pas l’état côté serveur. Elle doit donc être utilisée uniquement lorsque la partition réseau est suspectée, et le client et le serveur effectuent un nettoyage indépendant. Le serveur effectue un nettoyage indépendant via la routine d’exécution, le client le fait à l’aide de la fonction RpcSsDestroyClientContext .

Le fragment de code suivant présente un exemple de la façon dont un client peut utiliser un handle de contexte. Pour afficher la définition de l’interface utilisée par cet exemple, consultez Développement d’interface à l’aide de handles de contexte. Pour l’implémentation du serveur, consultez Développement serveur à l’aide de handles de contexte.

Dans cet exemple, le client appelle RemoteOpen pour obtenir un handle de contexte qui contient des données valides. Le client peut ensuite utiliser le handle de contexte dans les appels de procédure distante. Étant donné qu’il n’a plus besoin du handle de liaison, le client peut libérer le handle explicite utilisé pour créer le handle de contexte :

// cxhndlc.c  (fragment of client side application)
printf("Calling the remote procedure RemoteOpen\n");
if (RemoteOpen(&phContext, pszFileName) < 0) 
{
    printf("Unable to open %s\n", pszFileName);
    Shutdown();
    exit(2);
}
 
// Now the context handle also manages the binding.
// The variable hBindingHandle is a valid binding handle.
status = RpcBindingFree(&hBindingHandle);
printf("RpcBindingFree returned 0x%x\n", status);
if (status) 
    exit(status);

L’application cliente de cet exemple utilise une procédure appelée RemoteRead pour lire un fichier de données sur le serveur jusqu’à ce qu’elle rencontre une fin de fichier. Il ferme ensuite le fichier en appelant RemoteClose. Le handle de contexte apparaît en tant que paramètre dans les fonctions RemoteRead et RemoteClose comme suit :

printf("Calling the remote procedure RemoteRead\n");
do 
{
    cbRead = 1024; // Using a 1K buffer
    RemoteRead(phContext, pbBuf, &cbRead);
    // cbRead contains the number of bytes actually read.
    for (int i = 0; i < cbRead; i++)
        putchar(*(pbBuf+i));
} while(cbRead);
 
printf("Calling the remote procedure RemoteClose\n");
if (RemoteClose(&phContext) < 0 ) 
{
    printf("Close failed on %s\n", pszFileName);
    exit(2);
}