AngularJS: Aplicação em tempo real – Refresh periódico

Fala galera, beleza?

Depois de um mês atípico (muito trabalho e organizando casamento) e um começo de mês com ombro deslocado, estou de volta para delírio de vocês heheheh (menos né?!).

Hoje vou falar sobre aplicações em tempo real utilizando o padrão ajax de atualização periódica (periodic refresh) e como o AngularJS pode nos ajudar a implementá-lo. Deixa eu te fazer uma pergunta, você gostaria de ficar apertando F5 para verificar se há uma nova notificação no Facebook? Ou se chegou aquele e-mail que você tanto esperava no Gmail? Eu acho que não, né?

A fim de tornar a experiência do usuário a mais agradável possível, muitas aplicações utilizam dados em tempo real (ou quase) e até criam uma certa dependência dessa tecnologia, pois sem ela jamais teriam se popularizado.

Vamos ver esse refresh em funcionamento? Você tem Twitter? Se sim, acesse ele e depois abra o console do browser (aperte F12, abestado!). Na aba network, você pode verificar que periodicamente o twitter faz um GET, para checar se há alguma novidade a ser exibida ao usuário. Conforme mostra a figura abaixo:

twitter_console

Para exemplificar, vamos criar uma simples sala de bate-papo. Para o backend, utilizei a plataforma Java e para o frontend, a implementação foi feita com AngularJS usando o service $timeout.

$timeout

A galera do AngularJS resolveu encapsular o window.setTimeout dentro desse service. Quando o $timeout é chamado, ele retorna uma promise que será resolvida quando o delay for concluído e a função de timeout, caso exista, for executada.

Esse service tem a seguinte estrutura:

 $timeout([fn], [delay], [invokeApply], [Pass]); 

 

  • fn: A função a ser executada quando o delay acabar;
  • delay: O tempo limite em milissegundos. Valor default é zero.
  • invokeApply: Se o parâmetro for marcado como false o modelo de durty checking será ignorado, caso contrário, a função de tempo limite (fn) será chamada dentro do bloco $apply.
  • Pass: Aqui você pode passar parâmetros para a função a ser executada (fn).

O $timeout ainda nos fornece uma maneira de cancelar as tarefas que estão agendadas. Para isso, há o método $timeout.cancel([promise]). Ele recebe como parâmetro uma promise e, como resultado da execução, essa promise será resolvida com uma rejeição (rejection).

Backend com Java

Para o backend, usei os frameworks RestEasy para expor a API e o provider Jackson para consumir e produzir os objetos em JSON. Além disso, o projeto está com maven, utiliza Java 8 e está sendo executado no Tomcat. Ahhh! Ia esquecendo, está hospedado no heroku.

A aplicação implementada é bem simples, mas como não é o foco desse post, fiz só o necessário para o frontend funcionar. Os fontes do projeto estão no github.

A API exposta para uso consiste em:

  • GET /mensagens: listar as mensagens do chat;
  • POST /mensagens: enviar uma nova mensagem para a sala de bate papo;
  • DELETE /mensagens: apagar todas as mensagens da sala;

Frontend com AngularJS

Agora vamos falar da parte que mais nos interessa. Mas antes, como não sou lá essas coisas na parte de design, peguei a base do template para o chat nesse link aqui óh.

O gist abaixo apresenta a implementação da lógica necessária para realizar a atualização dos dados do nosso chat. O projeto completo pode ser visto no github e rodando aqui.

Analisando o gist acima, o acesso ao chat é feito pelo método entrar (linha 19). Ele é o responsável por ativar o refresh periódico através do método ativarRefresh (linha 24). Perceba que dentro desse método implementei um contador. Esse contador é decrementado a cada um segundo (1000 milissegundos) e quando o seu valor for zero o método atualizar (linha 27) será chamado. O contador está sendo utilizado na tela para informar ao usuário quanto tempo falta para a sala ser atualizada.

Os outros métodos apresentados no gist são:

  • cadastrar (linha 45):  responsável por enviar ao servidor uma nova mensagem;
  • sair (linha 33): é aqui que o método $timeout.cancel é chamado para finalizar a atualização periódica;
  • getContador (linha 53): retornar o contador a fim de informar quanto tempo falta para a próxima atualização do chat;
  • isAberto (linha 57): informar se o chat está aberto ou não.
  • listar (linha 61): listar as mensagens da sala de bate-papo.

Então é isso pessoal, essa é uma das formas de termos uma aplicação em tempo real. Fico esperando suas dúvidas e sugestões.

Só mais duas coisinhas:

  1. Para fazer a barra de rolagem automática do chat usei essa diretiva aqui;
  2. Esse artigo foi baseado em um post do Java Code Geeks.

Abraços e até a próxima!