Artigo original: How to build your own real-time chat app

Escrito por: Sudheesh Shetty

Os aplicações de mensagens estão ficando cada vez mais populares. Os últimos anos trouxeram aplicações como o WhatsApp, o Telegram, o Signal e o Line.

As pessoas parecem preferir aplicações baseadas em bate-papo, pois permitem interação em tempo real. Elas também adicionam um toque pessoal à experiência.

Recentemente, participei de um workshop conduzido pela Free Software Movement Karnataka (em português, Movimento de Software Livre Karnataka), em Bangalore, onde orientei um grupo de estudantes universitários.

Durante as interações, observei algumas coisas:

  1. Apesar de incentivar os alunos a interagir com o mentor, a comunicação sempre foi unilateral.
  2. Os alunos muitas vezes ficavam tímidos para fazer perguntas durante as sessões.
  3. Eles se sentiram mais à vontade para fazer perguntas e obter feedback em conversas individuais.

Então, tivemos que encontrar uma solução para quebrar o gelo entre mentores e alunos. Uma aplicação de bate-papo local foi útil nessa situação. As pessoas adoram ser anônimas, o que dá a elas mais poder para se expressar e perguntar a qualquer hora e em qualquer lugar. Este é o mesmo mantra usado pela maioria dos fóruns populares da internet, como o Reddit e o 4chan. Estes são apenas alguns exemplos gigantes de aplicações semianônimas.

Assim, comecei a pensar nessa ideia e criei alguns dos requisitos e recursos básicos.

  1. Os usuários se registram fornecendo um identificador, que é exclusivo para cada usuário (com um nome fictício). Apenas o identificador será revelado a outros usuários. Desse modo, as pessoas são livres para escolher qualquer identificador e, portanto, permanecem anônimas.
  2. Um membro pode ver outros membros que estão on-line. Eles têm a opção de ficar visíveis ao público, o que transmite sua mensagem para todos os membros on-line no bate-papo.
  3. Para mensagens privadas, o remetente deve primeiro enviar uma solicitação ao outro membro. Outros membros, ao aceitarem o pedido, podem ter um bate-papo privado com eles.

Tecnologias e ferramentas usadas

  1. A stack MEAN (Mongo, Express, Angular e Node).
  2. Sockets para permitir a comunicação individual em tempo real
  3. AJAX para inscrição e autenticação

Como criar uma aplicação de bate-papo simples?

Neste tutorial, vou ajudá-lo a criar sua própria aplicação de bate-papo. Posteriormente, você pode integrá-la como um widget em qualquer projeto! Este tutorial não se concentrará no desenvolvimento completo de uma aplicação de bate-papo. Ajudará, no entanto, a construir um.

Pré-requisito: você precisa ter algum conhecimento básico da stack MEAN, pois estamos fazendo uso dela para o projeto.

Primeiro, crie uma estrutura de diretório mais ou menos assim.

aholQChXQkfdRI26smzgqaGHiw0Ak82Yg7Gx
Estrutura de diretórios do projeto

Instale o Node.js e o MongoDB.

Usaremos o AngularJS 1 para este tutorial. Baixe a biblioteca do AngularJS aqui e copie-a para a pasta lib no diretório Client.

Se você gosta de embelezar a aplicação, pode baixar qualquer biblioteca do CSS e copiá-la para lib também.

Construindo o servidor

Passo 1 — Inicie o projeto:

Entre no diretório Server e execute este comando:

npm init

Um novo projeto será iniciado. Forneça todos os detalhes necessários. O package.json será criado e vai ter esta aparência:

{
  "name": "chat",
  "version": "1.0.0",
  "description": "Chat application",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your name",
  "license": "ISC"
}

Passo 2 — Instale as dependências.

  • socket.io — é uma biblioteca do JavaScript para aplicações da web em tempo real. Ele permite a comunicação bidirecional em tempo real entre clients e servidores da web.
  • express — é uma estrutura de aplicação da web do Node.js. Ele fornece o conjunto de recursos para desenvolver aplicações da web e para dispositivos móveis. Pode-se responder à solicitação HTTP usando diferentes middlewares e também renderizar páginas em HTML.
npm install --save socket.io
npm install --save express

Isso instalará as dependências necessárias e as adicionará ao package.json. Um campo a mais será adicionado ao package.json, que ficará assim:

"dependencies": {
    "express": "^4.14.0",
    "socket.io": "^1.4.8"
  }

Passo 3 — Criando o servidor

Crie um servidor que atenda na porta 3000 e que envie o documento html quando for chamado.

Inicie uma nova conexão de socket passando o objeto HTTP.

A conexão de evento estará escutando os sockets de entrada.

Cada socket emite um evento de desconexão que será chamado sempre que um client se desconectar.

  • socket.on espera pelo evento. Sempre que esse evento é acionado, a função de callback é chamada.
  • io.emit é usado para enviar a mensagem para todos os sockets conectados a ele.

A sintaxe é:

socket.on('evento', function(msg){})
io.emit('evento', 'mensagem')

Crie um servidor com o nome server.js. Ele deverá:

  • imprimir uma mensagem para o console após a conexão de um usuário
  • escutar eventos de mensagem de bate-papo e transmitir a mensagem recebida para todos os sockets conectados.
  • imprimir uma mensagem de desconexão no console sempre que um usuário se desconectar.

O servidor vai ter uma aparência semelhante a esta:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
  console.log('user connected');
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

Construindo o client

Crie o arquivo index.html no diretório Client, o arquivo style.css no diretório CSS e o arquivo app.js no diretório JS do client.

index.html:

Vamos escrever um HTML simples que possa receber nossa mensagem e também exibi-la.

Inclua socket.io-client e angular.js em elementos script no seu HTML.

<script src="/path/to/angular.js"></script>
<script src="/socket.io/socket.io.js"></script>

socket.io serve o client para nós. O padrão é se conectar ao host, que serve a página. O HTML final terá esta aparência:

<!doctype html>
<html ng-app="myApp">
  <head>
    <title>Socket.IO chat</title>
    <link rel="stylesheet" href="/css/style.css">
    <script src="/lib/angular/angular.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js">
    </script>
    <script src="/js/app.js"></script>
  </head>
  <body ng-controller="mainController">
    <ul id="messages"></ul>
    <div>
      <input id="m" ng-model="message" autocomplete="off" />
      <button ng-click="send()">Send</button>
    </div>
  </body>
</html>

CSS/style.css:

Dê um estilo para a aplicação fazendo com que se pareça uma caixa de bate-papo. Você pode usar qualquer biblioteca.

* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
div { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
div input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
div button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }

JS/app.js:

Crie uma aplicação com o angular.js e inicie uma conexão de socket.

  • socket.on escuta um determinado evento. Ele chama uma função de callback sempre que o evento for chamado.
  • socket.emit é usado para emitir a mensagem para o evento específico.

A sintaxe básica de ambos é:

socket.on('nome do evento', function(msg){});
socket.emit('nome do evento', mensagem);

Assim, sempre que a mensagem for digitada e o botão for clicado, chame a função para enviar a mensagem.

Sempre que o soquete receber uma mensagem, exiba-a.

O código em JavaScript ficará mais ou menos assim:

var app=angular.module('myApp',[]);

app.controller('mainController',['$scope',function($scope){
 var socket = io.connect();
 $scope.send = function(){
  socket.emit('chat message', $scope.message);
  $scope.message="";
 }
 socket.on('chat message', function(msg){
  var li=document.createElement("li");
  li.appendChild(document.createTextNode(msg));
  document.getElementById("messages").appendChild(li);
 });
}]);

Executando a aplicação

Vá para o diretório Server, onde nosso servidor está presente. Execute o servidor usando o seguinte comando:

node server.js

O servidor começa a rodar na porta 3000. Acesse o navegador e digite o seguinte url:

http://localhost:3000

Como melhorar a aplicação

Você pode criar um banco de dados para salvar detalhes e mensagens do usuário. Seria bom se o design fosse escalável para que você pudesse adicionar mais recursos posteriormente.

Você precisa instalar o Mongoose ou um módulo do MongoDB para usar um banco de dados do Mongo:

npm install --save mongoose

ou:

npm install --save mongodb

Aqui está a documentação para usar o mongoose e o módulo mongodb.
Aqui está a aparência do meu design de esquema:

{
 "_id" : ObjectId("5809171b71e640556be904ef"),
 "name" : "Sudheesh Shetty",
 "handle" : "sudheesh",
 "password" : "556624370",
 "phone" : "8888888888",
 "email" : "sudheeshshetty@gmail.com",
 "friends" : [
    {
      "name" : "abc",
      "status" : "Friend"
    },
    {
      "name" : "xyz",
      "status" : "Friend"
    }
 ],
 "__v" : 0
}

Aqui, o status de cada membro pode ser:

  • Friend: afirmando que o membro é um amigo.
  • Pending: se o membro ainda não aceitou.
  • Blocked: se o membro bloqueou o outro membro.

Suponha que o membro rejeitou uma solicitação de bate-papo. O remetente pode enviar uma solicitação de bate-papo novamente. Um usuário também pode salvar as mensagens criando uma coleção extra. Cada documento terá a mensagem, o remetente, o destinatário e a hora.

Portanto, projete seu banco de dados de acordo com suas necessidades específicas e como deseja tratar as mensagens.

2. Crie APIs REST para servir o client. Por exemplo, um terminal que envia uma página inicial, a partir da qual os usuários podem fazer outras solicitações.

Alguns dos meus endpoints de API são:

app.post('/register',function(req,res){})

app.post('/login',function(req,res){})

app.post('/friend_request',function(req,res){})

app.post('/friend_request/confirmed',function(req,res){})

3. Pense em alguns recursos adicionais interessantes e implemente-os.

O autor criou uma aplicação de bate-papo:

sudheeshshetty/Chat
Contribua com o desenvolvimento do Chat criando uma conta no GitHub

Aqui está uma rápida olhada na minha aplicação de bate-papo:

1-PmXr40QmsMiaRVejb1iS--qs3BqE2zINJE
Tela de autenticação
qQFOHwAEgl7k4DqVqRKVMlR1yd9c8T9I-388
Aparência da aplicação após a autenticação

Dê uma olhada na aplicação e, se gostar, dê a ela uma estrela. Há muitas maneiras de melhorar essa aplicação. Se tiver alguma sugestão, envie-a para o autor pelo e-mail sudheeshshetty@gmail.com.

Você pode seguir o autor no GitHub.