O documento discute a integração de sistemas usando a tecnologia XML-RPC, apresentando um ambiente onde Java é usada como plataforma de serviços consumidos por clientes em Delphi e .NET. O autor também descreve como implementou um servidor Java com diversos serviços e clientes em Delphi e .NET para consumi-los via XML-RPC.
1. - 1 -
Integração de sistemas com XML-RPC
Miguel Henley Filho
Vivemos hoje em um mundo onde a necessidade de integração de aplicações
é constante. Sistemas escritos, há anos ou até mesmo décadas, em linguagens
diferentes, sendo suportados por sistemas operacionais também diferentes
fazem parte da realidade nas empresas. Muitas vezes a integração entre esses
sistemas torna-se indispensável.
O objetivo desse artigo é apresentar a tecnologia XML-RPC como solução de
integração entre ambientes diferentes. O plano é configurarmos um ambiente
onde teremos Java como plataforma de serviços e, como client, aplicativos em
Delphi Win32 e .NET para consumi-los. O ambiente foi assim escolhido por ter
uma boa aproximação da realidade. A linguagem Java foi escolhida como
servidora por possuir um rico ecossistema com milhares de frameworks para
todos os gostos e necessidades bem como possuir a característica de
independência de plataforma, o que nos permitirá rodar o servidor em qualquer
sistema operacional que possua uma máquina virtual Java instalada (Windows,
Linux, Solaris, Mac OS, entre muitos outros).
O que é RPC?
RPC é o acrônimo de Remote Procedure Call, isto é, chamada remota de
procedimentos tendo sido criado há muito tempo, mesmo antes do nascimento
da internet. Veja a expressão abaixo:
resultado := computar(x, y, z, w)
Não seria maravilhoso se a chamada a essa função fosse totalmente
transparente para o desenvolvedor, não importando se a computação fosse
realizada no próprio hardware, no servidor da sala ao lado ou até mesmo em
um servidor do outro lado do mundo? Esse é o objetivo do RPC. Além disso,
não importa para o client nem para o server quais plataformas estão sendo
utilizadas em cada uma das pontas – essa informação é totalmente irrelevante.
Um desenvolvedor baixo nível poderá argumentar que com as linguagens de
hoje em dia um servidor poderia ser construído do zero para oferecer os
serviços a que ele se propõe, com relativa facilidade. Isso é verdade, mas
algumas coisas muito feias teriam que ser programadas como: threads, pool de
threads, sockets, segurança, chamadas assíncronas, entre outros. O esforço
seria muito grande uma vez que já temos disponível, em especificação e
implementação, a tecnologia XML-RPC.
A parte XML que prefixa a tecnologia XML-RPC é devido a troca de
mensagens entre o client e o server (solicitação – resposta) ser feita em um
2. - 2 -
vocabulário XML. Trata-se de uma especificação pública que qualquer um pode
implementar. Obviamente não estamos pensando em implementar essa
especificação pois outros já o fizeram. Implementações disponíveis existem
para muitas plataformas / linguagens: .NET, Java, Delphi, C++, Perl, Python,
Groovy, PHP, etc...
Em resumo, XML-RPC é uma especificação e um conjunto de implementações
que permitem sistemas realizarem chamadas a procedimentos remotos com
independência total da tecnologia utilizada, utilizando o conhecido protocolo
http como camada de transporte.
Uma das vantagens da utilização do http como transporte é tornar a
comunicação, entre os processos, simples evitando também dores de cabeça
com configurações de políticas em firewalls – quem já trabalhou com objetos
distribuídos utilizando CORBA ou DCOM 1sabe do que eu estou falando!
A figura 1 mostra o funcionamento básico do XML-RPC.
Figura 1
1
Aqui faço a comparação de CORBA / DCOM com XML-RPC somente no aspecto de leveza e facilidade
de configuração, pois são tecnologias muito diferentes.
3. - 3 -
No nosso exemplo simples de uma chamada a função computar (x, y, z, w), o
mecanismo XML-RPC, do lado client, montaria o seguinte trecho XML enviando
em seguida para o servidor. No exemplo x = 10, y = 20, z = 30 e w = 40:
--- cabeçalho (preâmbulo) ---
POST /rpchandler…
Host: laplace.exemplo.com…
Content-Type: text/xml
Content-Length: …
---
<?xml version="1.0"?>
<methodCall>
<methodName>app.Computar</methodName>
<params>
<param>
<value><i4>10</i4></value>
<value><i4>20</i4></value>
<value><i4>30</i4></value>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>
Listagem 1 – solicitação do client
No lado do servidor, após o parser do xml, a implementação faz o dispatcher
para o método computar, enviando os parâmetros x, y, z e w. Depois da
execução é montado uma reposta também xml e retornado ao client. Veja um
trecho de resposta possível – aqui supondo que computar realiza o somatório
dos parâmetros.
--- cabeçalho (omitido) ---
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><i4>100</i4></value>
</param>
</params>
</methodResponse>
</xml>
Listagem 2 – resposta do servidor
Cabe agora o client realizar o parser e obter a informação de resposta
desejada.
Tudo isso é feito em background e o desenvolvedor não precisa se preocupar
com detalhes de conexões, analisadores xml e dispatchers - salvo se quiser
implementar a especificação em sua linguagem favorita – uma boa atividade
para um final de semana chuvoso! Nesse caso é só baixar a especificação do
site http://www.xml-rpc.com
O padrão XML-RPC define alguns tipos de dados que podem ser trafegados
entre clientes e servidores. Na listagem 1 vemos tags <i4>. Esse elemento (i4)
representa os números inteiros na especificação – nossa hipotética função,
4. - 4 -
computar, precisa de 4 parâmetros inteiros!. A tabela 1 mostra os demais tipos.
Além desses tipos, estruturas e arrays também são suportados.
Tipo Tag XML Significado
Inteiro <i4> ou <int> Inteiro de 4 bytes com sinal = 32 bits
Double <double> Número de ponto flutuante
String <string> String
DateTime <datetime.iso8601> Data no padrão ISO 8601:
yyyymmddThh:mm:SS
Boolean <boolean> 1 = true, 0 = false
Byte[] <base64> Array de bytes
Tabela 1 – tipos suportados pelo XML-RPC
Devido ao XML-RPC utilizar o protocolo http como transporte, as comunicações
entre clientes e servidores são síncronas e sem estado (stateless). A
comunicação é dita síncrona quando há um “bloqueio” temporário do client
enquanto o server faz o processamento do que foi pedido – o client fica
bloqueado, esperando a resposta. Sem estado significa que nenhum estado é
guardado no servidor quando a resposta é retornada – pois a conexão é
sempre fechada quando a resposta é enviada ao cliente.
Mesmo assim é possível contornar com alguma facilidade esses “problemas”.
No caso de ser necessária uma chamada assíncrona, onde o client não precisa
ficar bloqueado, algumas implementações possuem formas de realizar isso – o
truque é enviar a solicitação ao servidor em um novo thread e programar um
método de callback para tratar o resultado. Para contornar a natureza stateless
a solução é um pouco mais braçal pois o server terá que ser programado para,
de alguma forma, identificar o client em chamadas subseqüentes e, além disso,
permitir armazenar as variáveis dos vários clients em zonas de memória
separadas – emulando sessões. Nesse caso uma estratégia de limpeza deve
existir e ser executada de tempos em tempos de acordo com um timeout
estabelecido.
Vamos ao lado server
Para tornar nosso cenário um pouco mais interessante vamos montar um
servidor com algumas funcionalidades não triviais - um exemplo do tipo “alô,
mundo” não seria nada atrativo. Então vamos oferecer os seguintes serviços.
a) Serviço para formatar um nome
Recebe como parâmetro um nome não formatado e o formata colocando
em letras maiúscula as inicias de cada nome e o resto em letras
minúsculas. Retira também o excesso de espaços em branco entre os
nomes. Por exemplo:
AlBeRtO SantoS DUMONT -> Alberto Santos Dumont
josé mauRo De vasconcelos -> José Mauro de Vasconcelos
b) Serviço para calcular o número PI (π) com qualquer quantidade de
casas decimais.
5. - 5 -
Recebe como parâmetro a quantidade de casas decimais para cálculo e
retorna um String contendo o resultado. Para os que não se lembram o
valor de PI pertence aos números irracionais e representa o quociente
entre o perímetro de uma circunferência e seu diâmetro. Não é possível
realizar esse cálculo com tipos primitivos de linguagem como double,
real ou extended - esses tipos tem precisão limitada.
c) Serviço para obter as fases da lua em um determinado mês.
Recebe como parâmetro o mês e o ano e retorna as fases da lua numa
escala inteira de 0 a 7. Sendo 4 a fase de lua cheia e 0 a fase de lua
nova – os outros números são os intermediários entre essas duas fases.
d) Serviço para fazer um post no twitter.
Recebe como parâmetro o login, senha e um status com no máximo 140
caracteres e realiza o post. Para isso, obviamente teremos que ter uma
conexão ativa com a Internet no lado server.
Essas implementações não poderiam ser programadas todas em Delphi e
colocadas dentro de um único executável? Sim, claro que poderiam. Só que
teríamos que colocar na balança se seria economicamente viável fazer o porte
– cada caso é um caso. Certa vez tive que realizar um trabalho de
programação baseada em regras utilizando lógica fuzzy. Programar essa lógica
do zero seria uma loucura e muito caro devido ao cronograma apertado e, não
existia (pelo menos na época) uma solução pronta para Delphi. A saída foi
utilizar uma biblioteca (das muitas existentes) em Java para lógica difusa. A
exceção do motor de inferência (que rodava no server), todo o sistema foi
desenvolvido em Delphi e a comunicação entre os processos feita em XML-
RPC.
Voltando ao nosso servidor, não vamos aqui dissecar a implementação de
cada um desses serviços. O Servidor é em Java e afinal de contas não
estamos na ActiveJava! Caso o micro que hospedará o servidor não tenha uma
máquina virtual Java (JVM) instalada é só baixar o JDK (Java Development Kit)
do JavaSE direto do site da Sun (http://www.javasoft.com) e fazer a instalação
que é muito simples (aquelas do tipo Next, Next, ..., Finish). Se o micro já
possuir uma JVM apenas assegure de que esteja instalado no mínimo o JDK
versão 5.
Depois disso faça o download do código fonte desse artigo e instale em uma
pasta qualquer, digamos: c:artigo_xmlrpc. Essa pasta possui tanto o lado
server como o lado client (cada um em sua respectiva subpasta). A
organização dos fontes do artigo está assim configurada:
client
dotNET
Win32
server
class
lib
src
build.xml
carga.bat
6. - 6 -
Dentro da pasta server, há um arquivo chamado carga.bat – edite esse arquivo
e onde se encontra a linha:
SET JAVA_HOME=......
Complete com o diretório onde foi instalado o JDK. Por exemplo, no meu micro:
SET JAVA_HOME=C:jdk1.6.0_11
Depois disso é só executar o script carga.bat – tenha preferência em executar
a partir da linha de comando pois caso venha a ocorrer algum erro na carga do
servidor, será mais fácil de visualizar. Veja a seqüência no console:
c:> cdartigo_xmlrpcserver [ Enter ]
c:artigo_xmlrpcserver> carga.bat [ Enter ]
.
.
Iniciando o servidor XML-RPC na porta 8081
Servidor pronto para integração ...
(Ctrl-C) para interromper
Pronto, nosso servidor já está pronto para receber as solicitações em XML-
RPC. Nota: Coloquei o servidor para ficar escutando uma porta diferente da
porta 80 (que é a padrão para http). Isso para não ocorrer conflito, pois nos
dias de hoje é raro um micro não ter um serviço http:80 iniciado. Se for
desejado modificar o numero da porta é só editar novamente o script carga.bat
e alterar o valor em SET SERVER_PORT. Essa variável está com 8081 por
default. Caso o leitor queira realizar a (re)compilação do servidor, é fornecido o
arquivo build.xml que deverá ser utilizado com a ferramenta ant.
Vamos ao lado Client
Aqui retornamos ao velho e bom Delphi. Primeiro vamos montar um client em
.NET utilizado o Delphi Prism e depois um client Win32 utilizando o Delphi 7.
Os dois clients irão consumir todos os serviços expostos no server.
Começamos primeiro com .NET
Client .NET
O client em .NET foi desenvolvido com Delphi Prism. A plataforma .NET não
possui suporte nativo a XML-RPC. Uma boa implementação é a XML-
RPC.NET e é preciso fazer o download em http://www.xml-rpc.net. A última
versão – até o momento que escrevo – é a 2.4.0. Baixe o arquivo xml-
rpc.net.2.4.0.zip e faça a descompactação em uma pasta qualquer. Localize na
descompactação a montagem CookComputing.XmlRpcV2.dll. Vamos precisar
somente dela. Os outros arquivos não são necessários, pois são constituídos
de: montagem para o Compact Framework, montagem para o NET Framework
versão 1, códigos fontes e testes – isso não nos interessa.
Devido a funcionalidade de reflexão presente na plataforma .NET, a
programação de um client é muito simples. Precisamos declarar uma interface
contendo os procedimentos remotos – listagem 3.
7. - 7 -
Type
[XmlRpcUrl('http://localhost:8081')]
IServicos = public interface
[XmlRpcMethod('app.formatarNome')]
method FormatarNome(s: String): String;
[XmlRpcMethod('app.obterPI')]
method ObterPI(casasDecimais: Integer): String;
[XmlRpcMethod('app.obterFasesLua')]
method ObterFasesLua(mes: integer; ano: integer): array of String;
[XmlRpcMethod('app.postarTwitter')]
method PostarTwitter(login: String; senha: String; post:String): String;
end;
Listagem 3 – declaração da interface no Delphi Prism
Repare que utilizamos atributos tanto no nível de interface quanto na
declaração dos métodos. Isso é necessário para que a reflexão seja feita e
uma classe proxy – que implementa essa interface – seja automaticamente
criada em tempo de execução.
O atributo XmlRpcUrl que aparece próximo a interface tem como parâmetro o
endereço (endpoint) do servidor. Já o atributo XmlRpcMethod que aparece em
cada método possui como parâmetro o nome do método correspondente
totalmente qualificado no server – o nome do método na interface pode ser
diferente do server, mas os tipos de parâmetros e de retorno devem ser iguais.
A qualificação tem o formato: namespace.procedimento. Daqui a pouco
falaremos mais sobre o objetivo do namespace.
O próximo passo é fazermos a chamada a esses procedimentos remotos. Para
que isso seja possível utilizamos a classe genérica XmlRpcProxyGen –
precisamos passar na construção desse objeto o nome da interface. Assim:
var servicos := XmlRpcProxyGen.Create<IServicos>;
Como podemos ver, a implementação da interface IServicos, que declaramos,
é feita de forma totalmente automática pelo XML-RPC.NET
E agora? Agora é só chamar os métodos:
var resultado :=
servicos.FormatarNome(‘douGlas aDamS’); // retorna Douglas Adams
var pi :=
servicos.ObterPI(35); // retorna 3.14159265358979323846264338327950288
.
.
var postar :=
servicos.PostarTwitter(‘mhenley@datamag.com.br’, ‘senha’, ‘Ola!!!’);
Obviamente a montagem CookComputing.XmlRpcV2.dll precisa ser
referenciada no Visual Studio (figura 2) – para isso basta clicar com o botão
8. - 8 -
direito no item References do projeto, no Solution Explorer, localizar e adicionar
a montagem à solução. As classes e interfaces estão contidas no namespace
‘CookComputing.XmlRpc’ dessa montagem. Para simplificar o client .NET foi
construído uma aplicação do tipo Console Application.
E isso é realmente tudo que precisamos fazer. A listagem 4 apresenta o código
fonte do client .NET e, na figura 3 temos a aplicação rodando.
namespace ClientPrism;
interface
uses
CookComputing.XmlRpc,
System.Text;
type
ConsoleApp = class
public
class method Main;
end;
implementation
class method ConsoleApp.Main;
begin
var servicos := XmlRpcProxyGen.Create<IServicos>;
// chama método remoto FormatarNome
Console.WriteLine();
Console.WriteLine('Método FormatarNome:');
var naoFormatado := 'mIgUeL hEnLEY';
var formatado := servicos.FormatarNome(naoFormatado);
Console.WriteLine('Nao formatado: ' + naoFormatado);
Console.WriteLine('Formatado : ' + formatado);
Console.WriteLine('------------------------------------------------');
Console.WriteLine();
// chama método para calcular o numero PI
Console.WriteLine('Método ObterPI: (50 casas decimais)');
var pi := servicos.ObterPI(50);
Console.WriteLine('Pi = ' + pi);
Console.WriteLine('------------------------------------------------');
Console.WriteLine();
// chama método para obter as fases da lua:
Console.WriteLine('Método ObterFasesLua: (maio/2009)');
Console.WriteLine('formato dia/mes/ano=[0-7]. 0=lua cheia, 7=lua nova');
Console.WriteLine();
var mes := 5;
var ano := 2009;
var fases := servicos.ObterFasesLua(mes, ano);
var strbuilder := new StringBuilder();
var dia := 1;
for each fase: String in fases do
begin
if dia <> 1 then
strbuilder.append('; ');
strbuilder.append(dia).
append('/').append(mes).append('/').append(ano).append('=').
append(fase);
inc(dia);
end;
10. - 10 -
Client Win32
Da mesma forma que acontece na plataforma .NET temos que baixar uma
implementação XML-RPC para Delphi Win32. Uma implementação é a
biblioteca Delphi XML-RPC que pode ser baixada do site sourceforge:
http://sourceforge.net/projects/delphixml-rpc/. Não é necessário baixar, pois o
download do artigo já contem essa biblioteca dentro da pasta
clientwin32dxmlrpc.
A última versão é a 2.0.0 e não há novos releases desde 2003. Essa versão
está homologada para Delphi 7 e faz uso dos componentes Indy para
comunicação TCP/IP. Como houve mudanças das API’s entre a versão 9 e 10
do Indy, versões posteriores do Delphi que utilizam o Indy 10 terão problema
para utilizar o Delphi XML-RPC. A solução é fazer as alterações “na unha” –
abrir o código fonte da biblioteca, sair à caça das chamadas ao Indy 9 e
adaptá-las ao Indy 10 – uma dica para quem quiser se aventurar nesse terreno
é utilizar alguns patterns2 como forma de isolamento entre o Delphi XML-RPC e
o Indy – isso facilitará futuros portes para novas versões do Indy que vierem a
aparecer.
A API do Delphi XML-RPC para o perfil client também é muito simples de
utilizar, porém, a configuração é um pouco mais trabalhosa em função da falta
do artifício de reflexão no Delphi Win32. Basicamente trabalhamos com uma
classe e duas interfaces: A classe TRpcCaller é a responsável por configurar o
endpoint (servidor + porta) e disparar a chamada ao servidor. O principal
método dessa classe é o Execute que recebe como parâmetro uma interface
do tipo IRpcFunction e retorna uma interface do tipo IRpcResult.
A interface IRpcFunction é implementada pela classe TRpcFunction e seus
principais métodos / propriedades são:
ObjectMethod – propriedade read/write que permite especificar o nome do
procedimento (totalmente qualificado) a ser executado no server.
AddItem – Métodos sobrecarregados que tem como objetivo “setar” os
parâmetros para o procedimento a ser executado no server. Exemplo: Se o
procedimento requer dois parâmetros: um string e um inteiro, as chamadas
devem ser assim realizadas (supondo obj um objeto do tipo IRpcFuntion):
obj.AddItem(‘parametro-string’); obj.AddItem(100); Também há sobrecarga
desse método para parâmetros do tipo array e estruturas.
Os principais métodos / propriedades da interface IRpcResult (resultado da
execução) são:
IsError – método que retorna um boolean. Retorna true se houve um erro no
server. (O procedimento pode – e deve - lançar exception caso alguma pré-
condição esteja fora do domínio de atuação).
2
Os patterns Factory e Adapter são bons candidatos para isso.
11. - 11 -
ErroMsg – propriedade read only que contem o erro lançado pelo servidor.
IsArray / IsBase64 / IsDate / IsFloat / IsInteger / IsString / IsStrut /
IsBoolean / IsBase64 – retorna true ou false se o resultado for um desses
tipos.
AsString / AsInteger / AsDateTime / AsBoolean / AsBase64 / AsArray /
AsStruct / AsFloat – para cada uma dessas propriedades retorna o seu
respectivo tipo (String, Integer, DateTime, ...). No caso do retorno ser um array,
a propriedade AsArray retorna a interface IRpcArray que possui formas de
obter os elementos através de índices. O retorno também pode ser uma
estrutura.
Conforme dito no inicio do artigo, a especificação XML-RPC também suporta
arrays e estruturas. Tipos array são muito úteis quando temos que passar para
o procedimento parâmetros multivalores – um procedimento remoto poderia
estar programado para calcular a média tendo como parâmetro de entrada um
array de double. Da mesma forma, o retorno do método pode ser multivalorado
– inclusive o servidor desse artigo oferece o método/procedimento
obterFasesLua que retorna um array de String contendo as fases da lua para
cada dia do mês. (nota: A especificação XML-RPC não impõe a
obrigatoriedade dos elementos de um array ser do mesmo tipo – podem ser de
tipos distintos – é possível misturar String com Array com Boolean com Array
de Array, etc...).
Quanto às estruturas, elas permitem um dicionário com armazenamento de
chave de busca ser trafegado entre o client e o server. Por exemplo, na
necessidade de trafegar uma estrutura como endereço (endereço, uf, cep, ...)
podemos utilizar a classe TRpcStruct - que implementa a interface
IRpcStruct. Essa interface possui métodos AddItem sobrecarregados – veja
na listagem 5 um trecho da interface extraído diretamente da unit
XmlRpcTypes.pas. Objetos do tipo IRpcStruct podem ser passados como
parâmetro para o método AddItem da interface IRpcFunction descrita
anteriormente.
type
…
IRpcStruct = interface(IInterface)
…
procedure AddItem(const Key: string; Value: Integer); overload;
procedure AddItem(const Key: string; const Value: string); overload;
procedure AddItem(const Key: string; Value: Double); overload;
procedure AddItem(const Key: string; Value: Boolean); overload;
procedure AddItem(const Key: string; Value: IRpcArray); overload;
procedure AddItem(const Key: string; Value: IRpcStruct); overload;
…
end;
Listagem 5 – parte da definição da interface IRpcStruct
A figura 4 mostra a interface visual do client Win32. Cada aba faz o acesso a
uma funcionalidade no servidor. A figura 5 mostra uma postagem no Twitter
realizada pelo client.
12. - 12 -
Figura 4 – interface client Win32
Figura 5 – postagem no Twitter
13. - 13 -
Voltando ao lado server
Vamos falar mais um pouco da implementação do servidor.
O pacote que permite o Java utilizar o XML-RPC (tanto como server ou client) é
o que está sob os auspícios da Apache Software Foundation e pode ser
encontrado em http://ws.apache.org/xmlrpc/ . Há outras implementações por aí,
mas essa é o padrão de fato3 para Java. Também não é necessário baixar
esse pacote, pois já o colocamos no arquivo de download do artigo.
Basicamente o que precisamos é utilizar somente a classe WebServer contida
no pacote org.apache.xmlrpc. Veja abaixo, o código relevante, que inicializa o
servidor:
1 public static void main(String[] args) {
2 System.out.println("Iniciando o servidor XML-RPC ...");
3 int port = getPort(args[0]);
4 WebServer ws = new WebServer(port);
5 ws.addHandler("app", new Servicos());
6 ws.start();
7 System.out.println("Servidor pronto para integração");
8 }
A linha 4 cria uma instância da classe WebServer passando como parâmetro o
numero da porta de escuta.
A linha 5 adiciona um handle ao servidor - o primeiro parâmetro define o nome
do namespace (definimos como app – mas poderia ter sido qualquer outro) e, o
segundo parâmetro é uma instancia da classe que queremos expor os métodos
ao mundo externo - classe Servicos - assim definida:
public class Servicos {
public String formatarNome(String uglyFormat) { … }
public String obterPI(int casasDecimais) { … }
public String[] obterFasesLua(int mes, int ano) { … }
public String postarTwitter(String login, String senha, String post) { … }
}
A implementação de cada método foi omitida - o código fonte completo está no
download do artigo e o leitor mais interessado poderá apreciar a forma que
essa classe foi implementada. Aqui fica a explicação prometida quanto a
qualificação do método/procedimento: namespace.procedimento. Podemos ter
vários procedimentos com mesmo nome, mas não no mesmo namespace.
Entre a linha 5 e a linha 6 poderíamos adicionar um outro handle da seguinte
forma: ws.addHandler(“app2”, new MaisServicos()). Fazendo isso todos os
métodos definidos na classe MaisServicos também seriam expostos e
poderiam ser invocados, pelo client, prefixando-os com “app2.”.
3
Padrões de jure (legais) são os desenvolvidos por organismos de padronização como ISO, ABNT, IEEE.
Padrões de fato são os estabelecidos pelo mercado, por sua grande utilização: PDF, MPEG, Windows,
etc...
14. - 14 -
A classe WebServer possui também funcionalidades de restrição de acesso por
IP. Podemos bloquear ou permitir o acesso por um determinado endereço, ou
faixa de endereços. Os métodos: acceptClient, denyClient e setParanoid dão
conta do recado e são muito úteis devido a natureza do XML-RPC – lembre-se
que o protocolo http é inseguro acarretando em uma troca de mensagens “clear
text” entre o client e o server. Se a segurança for um requisito para o seu
projeto o servidor deverá ser instalado em um web-server habilitado para SSL –
nesse caso o lembre-se que o cliente também deverá “falar” SSL.
Conclusão
No mundo real (e imperfeito) onde uma diversidade muito grande de
linguagens e sistemas operacionais se faz presente, é inevitável a necessidade
de integração entre sistemas rodando em plataformas distintas. XML-RPC se
destaca pela eficiência, portabilidade e, por uma curva de aprendizado muito
pequena, sendo uma solução leve, aberta e adequada para interoperabilidade.
Miguel Henley Filho (miguel.henley@gmail.com) é engenheiro e desenvolvedor de soluções
corporativas em Delphi e Java nas plataformas Windows e Linux. Possui interesse em
arquitetura de software, objetos distribuídos e algoritmos computacionais de alto desempenho.