Aplicação de Chat com Angular e Socket.IO
- Introdução
- Socket.Configuração do servidor IO
- Configurar estrutura de pastas
- Instalando pacotes locais
- Conectando ao Socket.IO
- Criar serviço para comunicação com o servidor
- Adicionando o serviço aos provedores de módulo
- Injetando o serviço em nosso componente
- Enviar uma mensagem para o Socket.IO
- Comunicando com outros usuários
Introdução
Usaremos RxJS, Angular, Express (Node.js) &Socket.IO para fazer uma aplicação de chat. Vamos ver o quão útil o RxJS pode ser neste cenário. Com o propósito de tornar as coisas mais suaves e fáceis estaremos usando Angular CLI para gerar a estrutura básica do cliente e nos obter uma placa de caldeira para a aplicação Angular mais simples de trabalhar. No back-end usaremos Node.js com express e Socket.IO. A razão por detrás disto é que o Socket.IO é muito fácil de configurar e de trabalhar. Além disso, ele fornece bibliotecas tanto do lado do servidor como do lado do cliente. Socket.IO usa principalmente o protocolo WebSocket para permitir a comunicação bidirecional em tempo real.
Se você quiser pular diretamente para a parte onde usamos RxJS para lidar com as mensagens de chat, clique aqui.
Vamos começar!
Socket.Configuração do servidor IO
Se você não tem o CLI Angular instalado você pode instalá-lo facilmente:
npm i -g @angular/cli
Configurar estrutura de pastas
Para manter as coisas limpas vamos criar uma nova pasta rxjs-chat para o nosso pequeno projeto. Deve servir como pasta raiz para Angular e Socket.IO apps.
Vamos criar uma aplicação Angular básica usando Angular CLI. Em nossa pasta de projetos execute seu terminal favorito e execute o seguinte comando:
ng new rxjs-chat
Dê-lhe um pouco de tempo. Depois de ter criado a estrutura básica e instalado os pacotes npm, renomearemos para cliente a pasta de projeto Angular recém-criada. Depois disso, na mesma pasta raiz criamos o servidor de pastas para o nosso servidor Socket.IO. Agora temos duas pastas dentro da nossa pasta rxjs-chat:
- client – Angular client app
- server – em breve será Node’s Socket.IO server
Instalando pacotes locais
Na pasta server vamos gerar o pacote.json executando o seguinte comando:
npm init -y
Depois disso instalaremos nossas dependências e as salvaremos em package.json:
npm install express socket.io --save
Na mesma pasta criaremos o arquivo index.js para a aplicação do nosso servidor. O conteúdo do arquivo deve ser o seguinte:
Criamos uma instância de express e armazenamo-la em app
variável. Depois disso criamos o servidor com o módulo http
. Depois passamos por express
para http.Server()
método. Express servirá como o manipulador de pedidos para o nosso servidor. Em troca obtemos a instância do servidor que armazenamos em server
variável.
Nas duas linhas de código seguintes ligamos o socket.IO com o nosso http server:
let socketIO = require('socket.io');
let io = socketIO(server);
node index.js
Conectando ao Socket.IO
Temos um servidor rodando na porta 3000. Agora é altura de ver como nos podemos ligar ao servidor a partir da nossa aplicação Angular. Para isso precisaremos instalar a biblioteca cliente Socket.IO. Vamos executar o seguinte comando na nossa pasta cliente:
npm install socket.io-client --save
>Por enquanto estamos nela vamos executar a aplicação Angular via Angular CLI:
ng serve -o
Agora temos a nossa aplicação em execução. Podemos ver que o nosso navegador padrão acabou de abrir uma nova aba apontando para o localhost. É por isso que usamos -o
argumento para abrir o navegador.
Criar serviço para comunicação com o servidor
I’am gonna name it chat.service.ts app.chat.service.ts e colocá-lo dentro da pasta src. O serviço vai ser o mais simples possível por enquanto:
Adicionando o serviço aos provedores de módulo
Ainda isso, vamos adicionar nosso ChatService aos provedores dentro do AppModule no arquivo app.module.ts:
Injetando o serviço em nosso componente
Finalmente, vamos importar e usar o serviço dentro do nosso componente app.part.ts file:
import { ChatService } from './app.chat.service';
E vamos injetar o ChatService em nosso construtor:
constructor(chatService: ChatService) { }
Como resultado, temos o seguinte arquivo:
Se tudo correu como esperado após salvar as alterações você deve ver a mensagem ‘user connected’ no terminal onde você iniciou o nodo app:
$ node index.js
started on port: 3000
user connected
Hence, podemos dizer que finalmente conseguimos nos conectar ao nosso servidor Socket IO. Agora é hora de realmente enviar alguns dados via Socket IO events.
Enviar uma mensagem para o Socket.IO
Tempo para melhorar o nosso até agora simples ChatService com uma opção para enviar uma mensagem para o servidor:
Para isto funcionar temos de usar sendMessage()
do nosso AppComponent:
Finalmente, vamos fornecer ao utilizador uma simples entrada de texto e um botão para que ele possa enviar uma mensagem:
Para que tudo isto funcione, temos de ouvir no servidor o evento ‘new-message’ que emitimos do ChatService:
socket.on('new-message', (message) => {
console.log(message);
});
Agora o nosso índice.js se parece com isto:
Se você quiser brincar com o código você pode encontrá-lo no meu repo GitHub – rxjs-chat.
Comunicando com outros usuários
Para que a nossa mensagem seja transmitida para outros usuários tudo o que temos que fazer é mudar a console.log(message)
na parte da nossa chamada de retorno do evento de ‘nova mensagem’ para io.emit(message)
:
E o que o io.emit() faz? Em palavras simples ele envia um evento para todos conectados ao servidor.
Vamos nos comunicar com o nosso servidor via ChatService. Vamos adicionar um novo método ao nosso serviço para este fim – getMessages
. Ele retornará um Observável que nós criaremos com o método Observable.create()
. Toda vez que o socket receber uma nova mensagem nós usaremos observer.next() para encaminhá-la aos observadores.
Após isso nós assinamos este Observável a partir de nosso AppComponent:
Criamos um novo messages
array onde armazenaremos as mensagens recebidas do servidor. Nós teremos que mostrar essas mensagens no nosso template. Este é o caso perfeito para ngFor:
.