Cliententwicklung mithilfe von Kontexthandles

Die einzige Verwendung, die ein Clientprogramm für ein Kontexthandle hat, besteht darin, es jedes Mal an den Server zu übergeben, wenn der Client einen Remoteprozeduraufruf ausgibt. Die Clientanwendung muss nicht auf den Inhalt des Handles zugreifen. Es sollte nicht versuchen, den Kontext mit Daten in irgendeiner Weise zu ändern. Die Remoteprozeduren, die der Client aufruft, führen alle erforderlichen Vorgänge im Kontext des Servers aus.

Bevor Sie ein Kontexthandle von einem Server anfordern, müssen Clients eine Bindung mit dem Server einrichten. Der Client kann ein automatisches, implizites oder explizites Bindungshandle verwenden. Mit einem gültigen Bindungshandle kann der Client eine Remoteprozedur auf dem Server aufrufen, die entweder ein geöffnetes (nicht NULL)-Kontexthandle zurückgibt oder einen [out] -Parameter in der Parameterliste der Remoteprozedur übergibt.

Clients können geöffnete Kontexthandles auf beliebige Weise verwenden, die sie benötigen. Sie sollten den Handle jedoch ungültig machen, wenn sie ihn nicht mehr benötigen. Hierfür gibt es zwei Möglichkeiten:

  • So rufen Sie eine remote Prozedur auf, die vom Serverprogramm angeboten wird, die den Kontext freigibt und das Kontexthandle schließt (legt es auf NULL fest).
  • Wenn der Server nicht erreichbar ist, rufen Sie die RpcSsDestroyClientContext-Funktion auf.

Der zweite Ansatz bereinigt nur den clientseitigen Zustand und sauber den serverseitigen Zustand nicht auf. Daher sollte er nur verwendet werden, wenn eine Netzwerkpartition vermutet wird, und der Client und der Server eine unabhängige Bereinigung durchführen. Der Server führt eine unabhängige Bereinigung über die Herunterlaufroutine durch, wobei der Client die RpcSsDestroyClientContext-Funktion verwendet.

Das folgende Codefragment zeigt ein Beispiel, wie ein Client ein Kontexthandle verwenden kann. Informationen zum Anzeigen der Definition der Schnittstelle, die in diesem Beispiel verwendet wird, finden Sie unter Schnittstellenentwicklung mithilfe von Kontexthandles. Informationen zur Serverimplementierung finden Sie unter Serverentwicklung mithilfe von Kontexthandles.

In diesem Beispiel ruft der Client RemoteOpen auf, um ein Kontexthandle abzurufen, das gültige Daten enthält. Der Client kann dann das Kontexthandle in Remoteprozeduraufrufen verwenden. Da das Bindungshandle nicht mehr benötigt wird, kann der Client das explizite Handle freigeben, das er zum Erstellen des Kontexthandles verwendet hat:

// 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);

Die Clientanwendung in diesem Beispiel verwendet eine Prozedur namens RemoteRead, um eine Datendatei auf dem Server zu lesen, bis ein Ende der Datei auftritt. Anschließend wird die Datei durch Aufrufen von RemoteClose geschlossen. Das Kontexthandle wird als Parameter in den Funktionen RemoteRead und RemoteClose wie folgt angezeigt:

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);
}