Tag Archive | json-rpc

JSON-RPC 2.0 com Phobos e Deimos

JSON-RPC é uma especificação que descreve como implementar técnicas RPC no seu sistema usando como base o formato JSON. O formato JSON é mais enxuto que o XML na maior parte dos casos, por possuir tipos primitivos como ints, floats e strings nativamente e não possuir a redundância que as tags do xml criam. Trabalhando no projeto BlowThemAll, cujo objetivo é criar um jogo no estilo do clássico Bomberman, mas que não só supere-o, mas também o leve a outro limite, o time optou por utilizar o JSON-RPC, versão 2.0, para toda comunicação entre os nós. Surgiu assim a necessidade de duas implementações (Qt e node.js) do JSON-RPC 2.0, e dessa necessidade surgiram as implementações Phobos & Deimos.

Phobos

Phobos é uma implementação do JSON-RPC 2.0 para Qt. Por não ter encontrado nenhuma implementação suficientemente boa para o jogo, eu a criei do 0. Possui as seguintes características:

  • Simétrica: Os dois lados da conexão podem enviar e receber chamadas remotas.
  • Completamente assíncrono: Graças ao padrão de signals & slots do Qt e seu loop de eventos, você pode tratar todas as chamadas em um sistema orientado a eventos, e tudo ocorrendo em uma mesma thread.
  • Simples: Há somente 3 classes para todo o projeto.
  • Completamente abstrata da camada de transporte: O que minha implementação faz é avisar quando há novas mensagens (que são do tipo QByteArray) para serem enviadas e disponibiliza métodos para tratar mensagens recebidas. Assim, caso você forneça um meio de transporte orientado a mensagens, pode utilizá-la para rodar no topo de qualquer camada (TCP, HTTP, …).
  • Não possui suporte a Batch (funcionalidade que só tem utilidade quando a camada de transporte é HTTP) e é licenciada sob os termos da licença GNU LGPL v3.

Nota: Phobos utiliza algumas características do novo padrão C++. Foi testada com o GCC 4.6.

Instalação/configuração

Há duas formas principais de configurar seu projeto para utilizar essa biblioteca. Um dos meios é embutir o código-fonte dela no seu projeto, cujo build precisa ser baseado no qmake. Esse é o meio de incluir a biblioteca “estaticamente”. Note que assim seu programa precisaria estar licenciado sob alguma licença compatível com a licença do projeto.

A outra forma de configurar a biblioteca seria configurando uma linkagem dinâmica, o que não colocaria nenhuma restrição de licenciamento no seu projeto. Por motivos de força maior (preguiça), colocarei aqui somente o meio fácil de configurar a biblioteca, que é embutindo seu código-fonte, mas acredito que se você tem experiência com Qt, não precisará de minha ajuda para configurar uma linkagem dinâmica.

NOTA: A Phobos depende de outra biblioteca para fazer o parse dos objetos JSON, a QJson. Não é complicado instalá-la. Ela possui arquivos para projetos a usarem através do cmake e do pkfconfig (o que eu uso) e está disponível no repositório oficial das distribuições linux mais importantes.

Baixe o arquivo phobos-1.0.tar.bz2 aqui e descompacte na raiz do seu projeto. Feito isso, adicione as seguintes linhas no arquivo .pro de seu projeto:

Agora seu projeto está pronto para utilizar a biblioteca.

Uso

Para implementar um sistema que se comunique através de JSON-RPC 2.0 usando a implementação Phobos, crie um objeto da classe Phobos::Peer e faça a conexão correta dos sinais:

Você então terá a responsabilidade de tratar o envio e o recebimento das mensagens. Caso esteja trabalhando com TCP, uma solução simples seria:

Agora o objeto peer está pronto para uso. Ele irá emitir o sinal readyRequest(QSharedPointer<Phobos::ResponseHandler>) sempre que uma nova requisição for recebida e o sinal readyResponse(QVariant,QVariant) quando houver uma nova resposta para uma de suas requisições, que são realizadas chamando o método call.

Há um exemplo completo na pasta phobos/examples e a documentação nos arquivos de cabeçalho está bem completa. Pretendo implementar as classes TcpHelper e HttpHelper, que irão tratar o envio e recebimento de mensagens para você, na versão 1.1.

Deimos

Deimos é uma implementação em javascript para node.js que apenas trata requisições/chamadas (você não pode usá-lo para fazer requisições/chamadas). Foi baseada no node-jsonrpc, que implementa o padrão 1.0 do formato. Deimos é uma implementação completa que suporta ambas as versões (1.0 e 2.0) do JSON-RPC e é licenciada sob a licença MIT.

Instalação

Sua instalação é muito simples, e requer apenas que você execute o seguinte comando dentro da pasta do seu projeto node.js:

Uso

Para permitir que seu servidor trate requisições JSON-RPC, primeiro importe a classe RpcHandler do módulo deimos:

Então toda vez que você receber uma requisição POST, pode tratá-la criando um novo objeto RpcHandler, passando como parâmetros os objetos request, response e um objeto contendo os métodos disponíveis:

Há um quarto argumento que o construtor de RpcHandler recebe, opcional, que indica se o modo de debug deve ser ativado. Se um dos métodos do objeto methods disparar uma exceção, o objeto RpcHandler vai responder com “Internal error” e a resposta pode ou não incluir a mensagem descrevendo a exceção, dependendo se o modo de debug está ou não ativo.

Suas funções sempre devem enviar uma mensagem de resposta exatamente uma vez. Essa mensagem é gerada automaticamente quando você chama response ou error (e suas variações). Se você quiser esconder sua função, simplesmente use o método methodNotFound. Verifique o arquivo deimos.js e a documentação do JSON-RPC 2.0 para mais informações.

Um pouco de cultura

Phobos e Deimos eram os deuses do horror e do terror, na mitologia grega. Eram irmãos-gêmeos, filhos de Ares, deus da guerra (fonte: wikipédia).

UPDATE:

Biblioteca Phobos atualizada (versão 1.1). Agora inclui as classes TcpHelper e HttpHelper, que abstraem o tratamento da camada de comunicação.

Programação 3 – parte 2

No último post da série, eu ainda não havia feito nenhuma linha de código, e estava decidido a fazer a parte principal do sistema em Python, até que eu li um artigo sobre Node.js e decidi que essa seria a tecnologia que eu utilizaria.

Você pode pensar no Node.js como um interpretador de Javascript que usa a engine V8 da google e adiciona uma API para tratar I/O de forma assíncrona, usando o paradigma de programação orientada a eventos. Essa abordagem resolve o problema c10k. Um servidor que usa a mesma abordagem para resolver o mesmo problema e é utilizado em ~7,65% de todos os domínios é o nginx.

Alguns problemas que eu enfrentei é que eu nunca tinha trabalhado com Javascript na vida, e junto com o fato de a tecnologia ser nova, tive dificuldades até para realizar a escolha dos módulos que eu iria utilizar.

Para criar os serviços, eu optei pelo uso do formato de dados JSON-RPC e pela implementação node-jsonrpc. Durante os testes com telnet, minha implementação dos serviços estava sempre falhando e explorando muito o problema (criei até uma ferramenta para me ajudar nos testes) descobri que era um bug na implementação do JSON-RPC, que ajudei a corrigir.

Para persistência, optei pelo banco de dados MongoDB, e pelo módulo mongoose, que ajudou-me inclusive na modelagem. O MongoDB é um banco de dados NoSQL escalável, de alta-performance e escrito em C++ que armazena objetos JSON.

Utilizei o módulo node-static, que inclusive faz cache, para servir os arquivos estáticos. O site que criei é simples, mas faz uso de tecnologias interessantes como HTML5 para os forms, o velho e já conhecido CSS e Javascript+dojo para fazer e tratar as requisições JSON-RPC.

Não tive tempo de criar uma aplicação gráfica completa a tempo para a entrega do trabalho, então fiz uma aplicação em Qt, que era nada mais que uma janela com um widget QWebView ao centro.

Posso afirmar que essa disciplina foi uma experiência interessante (principalmente comparada às outras disciplinas do curso de ciência da computação na UFAL). Caso queira os slides que eu criei para fazer o screencast anterior, use o link abaixo:

http://www.mediafire.com/?4ybe1njebvak0p9

%d blogueiros gostam disto: