Este exemplo nos dará a oportunidade de testar uma arquitetura versátil e robusta enquanto exercitamos alguns "músculos técnicos" que não são utilizados com frequência, seja porque nem sempre podemos utilizar as versões mais atuais das tecnologias como gostaríamos, ou porque simplesmente as aplicações que desenvolvemos no dia a dia não apresentam casos de uso que façam uso das características mais avançadas dos frameworks utilizados.
Durante muitos anos os desenvolvedores de sistemas para web precisaram recorrer a técnicas como Long Poll e Comet para contornar as limitações do padrão HTTP e simular a comunicação em mão dupla e tempo real entre servidor e cliente, visando criar aplicações com um nível de interatividade que se aproximasse daquelas encontradas no ambiente desktop.
Entretanto, desde a introdução da API JavaScript WebSocket como parte da especificação do HTML5, este tipo de subterfúgio não é mais necessário. A maior novidade que esta tecnologia apresenta é a quebra do paradigma request/response como nos habituamos a ver nas aplicações web. Isto porque, uma vez estabelecido o canal de comunicação entre cliente e servidor, qualquer um dos dois lados pode iniciar o envio de informações para a outra parte.
Outra vantagem é que esta comunicação ocorre sobre o protocolo TCP através da porta padrão (80), evitando a necessidade de configurações especiais de segurança. E a boa notícia é que a maioria dos browsers modernos já oferece suporte a esta tecnologia, e no lado servidor também já encontramos muitas implementações do padrão; se quisermos focar apenas no ecossistema Java, por exemplo, podemos citar o Tomcat 7, JBoss WildFly 8, Netty e Vert.x.
No entanto, por se tratar de uma tecnologia recente, o programador que tiver interesse em utilizá-la precisa tomar algumas medidas preventivas para o caso da mesma ainda não estar presente no navegador do usuário, fornecendo implementações alternativas do seu código que não invalidem a funcionalidade da sua aplicação.
Vamos mostrar como esta tarefa pode ser facilitada utilizando componentes do PrimeFaces 5.0, que possui uma integração muito boa com a API WebSocket tanto no lado JavaScript, quanto no lado Java.
Para demonstrar estas funcionalidades vamos criar uma aplicação que possibilite a vários usuários enviar dados para o servidor, ao mesmo tempo em que recebem atualizações sobre as ações dos demais usuários conectados. O exemplo escolhido para esta demonstração foi uma ferramenta web para votações em enquetes, através da qual os usuários enviarão seus votos e, ao mesmo tempo, acompanharão a contabilização dos resultados.
Esta comunicação entre cliente e servidor ocorrerá diretamente através de um canal WebSocket estabelecido entre os dois, de forma que as atualizações serão enviadas pelo servidor para o navegador do cliente sem a necessidade de uma requisição explícita por parte do usuário.
Nossa arquitetura de referência para realizar esta implementação reúne componentes bastante populares entre os desenvolvedores Java. Sendo assim, além do PrimeFaces 5.0, vamos utilizar o Tomcat 7 em conjunto com JPA 2.0 e JSF 2.2.
A infraestrutura de comunicação em tempo real da nossa aplicação ficará a cargo da API de WebSockets, que utilizaremos através do suporte oferecido pelo PrimeFaces.
Cabe salientar que a implementação de websockets que o PrimeFaces 5.0 utiliza não é o padrão puro, mas baseada no Atmosphere, um framework open source que pode ser utilizado de forma integrada com qualquer aplicação web Java.
Entretanto, o mesmo não se tornou famoso por sua facilidade de configurar e integrar. Por sorte, graças a uma parceria firmada entre a Primetek (empresa por trás do PrimeFaces) e a Async-IO (companhia responsável pelo Atmosphere), a integração entre os dois frameworks foi bastante simplificada.
Uma das ações tomadas foi deixar para trás a configuração mais verbosa via XML, que foi substituída por uma nova API configurada via anotações. Isto significa código mais simples, limpo, e consequentemente menos propenso a erros.
Uma boa justificativa para o PrimeFaces basear sua implementação de WebSockets no framework Atmosphere pode ser explicado pelo fato da JSR 356 interagir apenas com browsers que suportem o protocolo de WebSocket. Assim, se o programador utilizasse a implementação pura da JSR 356, a aplicação em produção, a ser acessada por usuários que possuem navegadores que não oferecem suporte a WebSockets, simplesmente não funcionaria.
Já com Atmosphere isso não acontece, pois é capaz de substituir de forma transparente a camada de transporte por outro tipo, como HTTP, sem que seja necessária nenhuma alteração no código fonte.
Visão geral da arquitetura
Para a implementação dos conceitos que serão discutidos neste artigo, foi selecionada uma combinação de componentes de software bastante interessante por sua simplicidade, mas que ao mesmo tempo às vezes é rejeitada em detrimento a soluções pré-configuradas como, por exemplo, containers Java EE mais robustos como GlassFish ou JBoss.
A intenção é que o leitor tenha à sua disposição, ao final deste artigo, além do componente JSF que iremos mostrar como construir, uma aplicação exemplo cuja arquitetura possa ser utilizada como inspiração para várias outras aplicações simples, e que não demandariam todo o poder oferecido por um container Java EE completo.
O projeto será configurado utilizando o gerenciador de dependências Maven, o que visa facilitar a vida do leitor. Entretanto, se você não domina esta ferramenta, não se preocupe, porque também vamos utilizar a IDE Eclipse, que disponibiliza suporte a projetos Maven. O importante a ressaltar aqui é que todas as dependências do projeto serão listadas em um único arquivo POM.
As principais tecnologias que irão compor nossa solução são:
·
Aplicação e interface com
usuário: PrimeFaces 5, JSF-API 2.2.6 e JSF-IMPL 2.2.6, WebSocket ...