# Chamada de procedimento remoto

Chamada remota de procedimento (RPC, acrônimo de Remote Procedure Call) é uma tecnologia de comunicação entre processos que permite a um programa de computador chamar um procedimento em outro espaço de endereçamento (geralmente em outro computador, conectado por uma rede). O programador não se preocupa com detalhes de implementação dessa interação remota: do ponto de vista do código, a chamada se assemelha a chamadas de procedimentos locais.
RPC é uma tecnologia popular para a implementação do modelo cliente-servidor de computação distribuída. Uma chamada de procedimento remoto é iniciada pelo cliente enviando uma mensagem para um servidor remoto para executar um procedimento específico. Uma resposta é retornada ao cliente. Uma diferença importante entre chamadas de procedimento remotas e chamadas de procedimento locais é que, no primeiro caso, a chamada pode falhar por problemas da rede. Nesse caso, não há nem mesmo garantia de que o procedimento foi invocado.

## História

A ideia de RPC data de 1976, quando foi descrito no RFC 707. Um dos primeiros usos comerciais da tecnologia foi feita pela Xerox no "Courier", de 1981. A primeira implementação popular para Unix foi o Sun RPC (atualmente chamado ONC RPC), usado como base do Network File System e que ainda é usada em diversas plataformas.
Outra implementação pioneira em Unix foi o Network Computing System (NCS) da Apollo Computer, que posteriormente foi usada como fundação do DCE/RPC no Distributed Computing Environment (DCE). Uma década depois a Microsoft adotou o DCE/RPC como base para a sua própria implementação de RPC, MSRPC, a DCOM foi implementada com base nesse sistema. Ainda no mesmo período da década de 1990, o ILU da Xerox PARC e o CORBA ofereciam outro paradigma de RPC baseado em objetos distribuídos, com mecanismos de herança.
De forma análoga, atualmente utiliza-se XML e JSON como linguagem de descrição de interface e HTTP como protocolo de rede para formar serviços web, cujas implementações incluem SOAP, REST e XML-RPC.

## O Modelo

O modelo de Chamada Remota de Procedimento é similar ao modelo de chamadas locais de procedimentos, no qual a rotina que invoca o procedimento coloca os argumentos em uma área de memória bem conhecida e transfere o controle para o procedimento em execução, que lê os argumentos e os processa. Em algum momento, a rotina retoma o controle, extraindo o resultado da execução de uma área bem conhecida da memória. Após isso, a rotina prossegue com a execução normal.
No modelo RPC, o processo de invocação ocorre de maneira similar. Uma Thread é responsável pelo controle de dois processos: invocador e servidor. O processo invocador primeiro manda uma mensagem para o processo servidor e aguarda (autobloqueia) uma mensagem de resposta. A mensagem de invocação contém os parâmetros do procedimento e a mensagem de resposta contém o resultado da execução do procedimento. Uma vez que a mensagem de resposta é recebida, os resultados da execução do procedimento são coletados e a execução do invocador prossegue.
Do lado do servidor, um processo permanece em espera até a chegada de uma mensagem de invocação. Quando uma mensagem de invocação é recebida, o servidor extrai os parâmetros, processa-os e produz os resultados, que são enviados na mensagem de resposta. O servidor, então, volta a esperar por uma nova mensagem de invocação.
Nesse modelo, apenas um dos dois processos permanece ativo, em um dado instante de tempo. No entanto, esse modelo serve apenas de ilustração. O protocolo ONC RPC não faz restrições à implementações que permitam concorrência entre esses processos. Por exemplo, uma implementação poderia optar por chamadas assíncronas, que permitiriam ao cliente continuar com o trabalho útil, enquanto estivesse aguardando a mensagem de resposta.
Uma chamada remota de procedimento difere das chamadas locais em alguns pontos:
* Tratamento de erros: falhas do servidor ou da rede devem ser tratadas.
* Variáveis globais e efeitos colaterais: Uma vez que o servidor não possui acesso ao espaço de endereços do cliente, argumentos protegidos não podem ser passados como variáveis globais ou retornados.
* Desempenho: chamadas remotas geralmente operam a velocidades inferiores em uma ou mais ordens de grandeza em relação às chamadas locais.
* Autenticação: uma vez que chamadas remotas de procedimento podem ser transportadas em redes sem segurança, autenticação pode ser necessário.
Dessa forma, mesmo havendo diversas ferramentas que geram automaticamente o cliente e o servidor, os protocolos precisam ser desenvolvidos cuidadosamente.

## Semântica de Transporte

O protocolo RPC pode ser implementado sobre diferentes tipos de protocolos de transporte, uma vez que é indiferente a maneira de como uma mensagem é transmitida entre os processos. É importante salientar que o protocolo RPC não implementa nenhuma forma de confiabilidade e que a aplicação precisa tomar cuidados quanto ao tipo de protocolo sobre o qual RPC opera. Caso se trate de um protocolo confiável, como TCP, as preocupações com confiabilidade já são resolvidas. Por outro lado, caso a camada de transporte seja não-confiável, como UDP, mecanismos de timeout, retransmissão e detecção de duplicatas devem ser implementados, uma vez que esses serviços não são providos por RPC.
Devido à independência da camada de transporte, o protocolo RPC não modifica a semântica das chamadas remotas, nem seus requisitos de execução. A semântica pode ser inferida a partir da camada de transporte em uso. Por exemplo, considere o caso em que RPC opera sobre uma camada de transporte não-confiável, como UDP. Se uma aplicação retransmite mensagens de invocação RPC, após timeouts, e não recebe respostas, não pode inferir o número de vezes em que o procedimento foi executado. Se uma mensagem é recebida, ela pode inferir que o procedimento foi executado, pelo menos, uma vez. O servidor pode efetuar o controle do número de execuções, simplesmente gravando o número do último procedimento executado com êxito, evitando assim reexecuções de uma mesma chamada.
Por outro lado, quando RPC opera sobre uma camada de transporte confiável, como TCP, a aplicação pode inferir, a partir de uma mensagem de resposta, que o procedimento foi executado exatamente uma vez. No entanto, se nenhuma mensagem de reposta é recebida, a aplicação não pode assumir que o procedimento não foi executado. Perceba que, mesmo usando um protocolo orientado a conexões, aplicações ainda requerem timeouts para identificar falhas do servidor.
Há, ainda, muitas outras possibilidades de transporte além de datagramas e protocolos orientados a conexão. Por exemplo, protocolos de consulta-resposta como VMTP pode ser usado por TCP.

## Implementando RPC

Para permitir que os servidores sejam acessados por diferentes clientes, diversos sistemas padronizados de RPC foram criados. A maioria deles usa uma linguagem de descrição de interface (IDL) para que diferentes plataformas possam chamar procedimentos. Fazendo uso de uma ferramenta como o RPCGEN, pode-se gerar interfaces entre cliente e servidor a partir de um arquivo IDL, os chamados stubs. Como os stubs são embarcados nas aplicações cliente e servidor, a RPC não é uma camada de middleware.
Na codificação, o procedimento remoto do cliente chama o stub cliente como qualquer outro procedimento local, e a implementação interna do stub cliente é responsável por iniciar o processo de transmissão para stub servidor, empacotando a chamada numa mensagem. Ao chegar, o stub servidor desempacota a mensagem e invoca localmente o procedimento, aguardando o retorno. Quando a chamada local retorna, o stub servidor é responsável por iniciar o processo de transmissão para o stub cliente, empacotando a resposta numa mensagem. Chegando, a resposta é desempacotada pelo stub cliente, sendo retornada localmente para o procedimento que realizou a chamada remota.
Ao invocar o procedimento remoto, deve-se atentar que cliente e servidor podem ser plataformas diferentes, que representam dados de forma diferente. Nesse caso é preciso um protocolo comum de representação dos dados, como o XDR, ou a garantia de que ambas as partes saibam converter os dados para tipos de dado suportados. Por ser uma chamada remota, noutro espaço de endereçamento, deve-se atentar também o desafio de passar um ponteiro. Nesse caso, a implementação interna do RPC deve passar o conteúdo do ponteiro por cópia e restaurar a área de memória no retorno do procedimento.

## Limitações

Diferentes implementações de chamada de procedimento remoto costumam ser incompatíveis entre si, ainda que existam exceções. Por isso, o uso de uma determinada implementação, provavelmente, resultará na dependência com o fornecedor da implementação. Essa incompatibilidade entre implementações se mostra também na disponibilidade de funcionalidades, no suporte a diferentes protocolos de rede e diferentes sistemas de arquivo.
A maioria das implementações não suporta P2P e ou interação assíncrona entre cliente e servidor (por definição, a chamada remota corresponde a uma chamada local do ponto de vista da aplicação, bloqueante da mesma forma). A comunicação síncrona implica a disponibilidade constante tanto do cliente quanto do servidor.

## Implementações

* CORBA — padrão RPC independente de plataforma
* Sun RPC — RPC para as plataformas Unix e Linux
* DCOM — RPC para Windows
* RMI — RPC para Java
* SOAP — padrão RPC para web service
* JRES - Java Remote Execution Service é um protocolo RPC que usa um mecanismo de codificação estilo SSL para codificar suas chamadas e HTTP puro como mecanismo de transporte.