Desenvolvimento do cliente usando identificadores de contexto

O único uso que um programa cliente tem para um identificador de contexto é passá-lo para o servidor sempre que o cliente fizer uma chamada de procedimento remoto. O aplicativo cliente não precisa acessar o conteúdo do identificador. Ele não deve tentar alterar os dados do identificador de contexto de forma alguma. Os procedimentos remotos invocados pelo cliente executam todas as operações necessárias no contexto do servidor.

Antes de solicitar um identificador de contexto de um servidor, os clientes devem estabelecer uma associação com o servidor. O cliente pode usar um identificador de associação automático, implícito ou explícito. Com um identificador de associação válido, o cliente pode chamar um procedimento remoto no servidor que retorna um identificador de contexto aberto (não NULL) ou passa um por meio de um parâmetro [out] na lista de parâmetros do procedimento remoto.

Os clientes podem usar identificadores de contexto abertos da maneira que precisarem. No entanto, eles devem invalidar o identificador quando não precisarem mais dele. Há duas maneiras de fazer isso:

  • Para invocar um procedimento remoto oferecido pelo programa de servidor que libera o contexto e fecha o identificador de contexto (define-o como NULL).
  • Quando o servidor estiver inacessível, chame a função RpcSsDestroyClientContext .

A segunda abordagem só limpa o estado do lado do cliente e não limpo o estado do lado do servidor, portanto, ela deve ser usada somente quando houver suspeita de partição de rede, e o cliente e o servidor farão uma limpeza independente. O servidor executa a limpeza independente por meio da rotina de execução, o cliente faz isso usando a função RpcSsDestroyClientContext .

O fragmento de código a seguir apresenta um exemplo de como um cliente pode usar um identificador de contexto. Para exibir a definição da interface que este exemplo usa, consulte Desenvolvimento de interface usando identificadores de contexto. Para a implementação do servidor, consulte Desenvolvimento de servidor usando identificadores de contexto.

Neste exemplo, o cliente chama RemoteOpen para obter um identificador de contexto que contém dados válidos. Em seguida, o cliente pode usar o identificador de contexto em chamadas de procedimento remoto. Como ele não precisa mais do identificador de associação, o cliente pode liberar o identificador explícito usado para criar o identificador de contexto:

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

O aplicativo cliente neste exemplo usa um procedimento chamado RemoteRead para ler um arquivo de dados no servidor até encontrar um fim do arquivo. Em seguida, ele fecha o arquivo chamando RemoteClose. O identificador de contexto aparece como um parâmetro nas funções RemoteRead e RemoteClose como:

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