Aplicação Real-Time com Rails 5

vicente correia
Jaguaribe Tech
Published in
6 min readAug 31, 2017

Olá pessoal, estou aqui novamente, dessa vez vim trazer para vocês um assunto muito bacana que é WebSocket, nesse artigo vou falar um pouco sobre essa tecnologia, como o Rails a utiliza e mostrar o exemplo de uma aplicação, preparados? Então lá vamos nós…

WebSocket

A final de contas, o que é websocket? A web é toda baseada no protocolo HTTP onde temos um cliente fazendo uma requisição para o servidor.

Quando o cliente faz uma requisição para o servidor, uma conexão é aberta, criando um canal de comunicação, assim que a requisição chega ao servidor ele processa os dados e devolve uma resposta para o cliente pelo mesmo canal, logo em seguida o canal é fechado.

Em alguns casos as pessoas necessitavam que o servidor enviasse uma resposta para o cliente, com isso elas precisavam que o cliente enviasse novamente uma requisição para o servidor de maneira que ele pudesse responder, em certos casos isso pode ocasionar alguns problemas, pois se nós ficarmos fazendo muitas requisições e criarmos muitas conexões poderia ocasionar uma sobrecarga de requisições HTTP no servidor, já o WebSocket funciona de uma maneira diferente, ele cria uma conexão contínua(ws) do cliente com o servidor.

A conexão contínua existirá até o cliente se desconectar ou o servidor informar que a conexão deverá ser excluída. Na conexão contínua o cliente pode enviar vários dados para o servidor, e o servidor, sem que seja necessário o cliente enviar requisições, pode também enviar dados para o cliente. Esse tipo de cenário é bastante utilizado em bate-papo, jogos multiplayer, atualizações em tempo real de redes sociais. Trello, Slack, Pusher e tantos outros, são exemplos de serviços que fazem grande uso de WebSockets, consultado o nosso amigo Wikipedia ele diz que:

“WebSocket é uma tecnologia que permite a comunicação bidirecional por canais full-duplex sobre um único soquete Transmission Control Protocol (TCP). Ele é projetado para ser executado em browsers e servidores web que suportem o HTML5, mas pode ser usado por qualquer cliente ou servidor de aplicativos.”

E no Rails, como funciona?

A partir do Rails 5 temos uma forma simples de implementar WebSocket, através do Action Cable, que facilita a criação de funcionalidades real-time na sua aplicação. Para isso ele faz um mix de tecnologias e libs:

  • Redis: utilizado para armazenar as mensagens.
  • websocket-driver-ruby: para ajudar na comunicação com WebSockets.
  • concurrent-ruby: Para trabalhar com Thread Pools.

Criar um app usando o action cable pode ser muito mais eficiente e elegante do que fazer inúmeras chamadas repetitivas para o backend via AJAX e etc, além disso podemos criar qualquer tipo de App que dependa de uma interação em tempo real do back-end com o front end.

Temos dois conceitos que precisamos entender antes de começar a botar a mão na massa no nosso exemplo prático.

Connections: As connections formam a base do relacionamento cliente-servidor. Para cada WebSocket aceito pelo servidor, um objeto de conexão é instanciado.

Channels: Um channel encapsula uma unidade lógica de trabalho, semelhante ao que um controller faz em uma configuração MVC regular. Por padrão, o Rails cria uma classe de ApplicationCable :: Channel para encapsular lógica compartilhada entre seus channels.

Exemplo prático

No nosso exemplo vamos criar um chat real time utilizando o Action Cable.

Pré-requisitos

  • ruby version ≥ 2.3
  • rails version ≥ 5

Vamos dar início ao nosso chat

Primeiramente, no seu console crie um novo aplicativo Rails, vamos chamar de my_chat, digite o comando:

$ rails new my_chat

Com o aplicativo gerado, vamos criar o primeiro controller para responder as mensagens do chat, para isso entre na pasta do projeto e execute:

$ rails g controller chats show

Com o controller gerado, vamos agora fazer o nosso chat devolver as mensagens do sistema criando o model messages, mas antes vamos abrir o nosso controller gerado para implementarmos o método show, no arquivo insira o seguinte código:

my_chat/app/controllers/chats_controller.rb

Agora vamos criar o model, ele terá um campo content do tipo text, com o comando:

$ rails g model message content:text

Com o model Message gerado, vamos criar um diretório dentro da pasta app/view chamado messeges e dentro desse novo diretório criaremos um arquivo chamado _message.html.erb, agora vamos abrir esse arquivo e inserir o seguinte conteúdo:

Vamos abrir a view que foi gerada no show do chat, e modificar ela com o seguinte conteúdo:

my_chat/app/views/chats/show.html.rb

Esse conteúdo irá chamar as mensagens definidas no arquivo anterior passando umas messages para ele e será mostrada todas as mensagens que foram criadas no sistema, isso porque no nosso chat nós podemos enviar mensagens e ver as mensagens que as pessoas estão mandando como resposta.

Agora vamos gerar um channel, execute o comando:

$ rails g channel chat speak

Vamos lá, no nosso arquivo de rotas para incluir uma rota para o action cable, o channel gerado logo acima. Abra o arquivo e insira o seguinte código:

my_chat/config/routes.rb

Essa será a rota para o action cable, caso nosso projeto fosse mais complexo, precisaríamos de outras rotas.

Criamos um model anteriormente, então vamos rodar nossa migrate, execute o comando:

$ rake db:migrate 

Migrate criada? vamos dar uma olhada no nosso código! Se você observar no diretório channel que foi gerado, temos um arquivo chamado chat_channel.rb e nele contém a estrutura de algumas funções que basicamente mostram a maneira como você inscreve um usuário na hora que ele entra no html do chat. Essa é a parte do back-end mas ele também gera o front end, entre no diretório app/assets/javascripts/channels e temos o arquivo chat.coffee que é basicamente o espelho do que temos no back-end.

Vamos ver se está tudo ok?

Para verificar se até o momento está tudo ok, suba o servidor:

$ rails s

e acesse a url localhost:3000, o esperado é uma página assim:

Agora vamos fazer as alterações necessárias no código do front end, que é o chat.coffee, abra o arquivo e insira o seguinte código:

Lá no nosso models/message.rb, vamos inserir o seguinte código:

O código serve para que ao colocarmos uma nova mensagem no message ele chame o ChatBroadcastjob.perform_later, ou seja vamos criar um job para tratar essas mensagens. Agora nós precisamos criar esse ChatBroadcastjob, para isso pare o servidor e execute o seguinte comando:

$ rails g job ChatBroadcast

Com o arquivo do job criado, vamos alterar ele e inserir o seguinte código:

my_chat/app/jobs/chat_broadcast_job.rb

Vamos testar?

Ok! com todos os arquivos configurado, vamos fazer o teste, abra duas abas no browser e tente conversar, observe que o que você digita em uma tela aparece na outra em tempo real, isso no nosso aplicativo simples mas pode ser implementado em projetos mais robustos, ficaria algo assim:

Conclusão

Usando o Active Cable nós podemos fazer coisas muito legais, então se você quer construir um App que precisa de comunicação em real time de uma maneira profissional na plataforma do Rails, o Active Cable é o caminho para você. O código desse projeto está disponível no meu github, caso quera saber mas acesse a documentação do Action Cable espero que tenham gostado e até a próxima :)

--

--