Neste tutorial iremos abordar alguns conceitos do Socket.io criando um simples sistema de chat para browser.
Socket.io é um uma biblioteca Javascript feita para construir aplicações real-time, possibilitando uma comunicação bi-direcional entre cliente e servidor. O socket.io utiliza as especificações de Web Sockets (para quem quer saber mais, recomendo dar uma olhada neste ótimo artigo da HTML5 Rocks).
O Socket.io roda, no lado do servidor, em NodeJS, e, no lado do cliente, ele roda diretamente no browser, possibilitando uma enorme gama de possibilidades de aplicações, como jogos, sistemas de notificações, real-time analytics e sistemas de chats e conversas em tempo real.
Setando o projeto
Primeiramente, temos que instalar algumas bibliotecas que iremos utilizar no projeto, para isso usarei o yarn.
Em primeiro lugar, vou adicionar ao projeto a biblioteca do Socket.io que rodará do lado do servidor.
Também iremos utilizar o express:
Também precisamos adicionar o Socket.io para o cliente (você pode utilizar a CDN oficial disponibilizada no site deles também):
E, por último, usarei a biblioteca jQuery para manipular a DOM.
Fazendo o HTML+CSS
Vamos criar um arquivo index.html e já deixar preparado o nosso template do sistema de chat.
Repare que eu também criei o diretório assets, e criei os arquivos css.css e js.js.
Não entrarei na parte do CSS, pois o foco aqui é o javascript, mas você pode ver o resultado no github. Eu utilizei como base este pen para construir o layout.
Server-side
Vamos iniciar com a criação da parte de servidor do Socket.io, ou seja, iremos lidar com os eventos server-side.
Iniciaremos criando um arquivo app.js no diretório raíz e importaremos os módulos e faremos algumas operações iniciais:
Este script implementa um servidor Node utilizando os módulos http e express (para roteamento).
A variável clientes que está sendo criada servirá para armazenar nossa lista de clientes.
Agora iremos adicionar o nosso primeiro evento do Socket.io, que será o connection, que dispara a cada vez que um cliente se conecta ao socket.
Para nossa sala de chat, precisaremos implementar outros 3 eventos: join, send e disconnect:
O evento join deverá ser disparado quando o cliente entrar no servidor, adicionando o id do cliente no array e emitindo dois novos eventos, nomeando-os de update.
Note que há uma diferença entre o método client.emit e o client.broadcast.emit. O client.emit enviará a notificação somente para o cliente atual, ou seja, o cliente que acabou de entrar na sala de chat. O client.broadcast.emit irá emitir para todos os clientes conectados, com exceção do que está executando a ação. Se utilizássemos o método io.emit, a mensagem seria enviada a todos os clientes conectados ao socket. Abaixo uma série de exemplos de métodos disponíveis:
Com todos esses métodos, conseguiríamos implementar salas específicas, mensagens individuais, etc. Porém nosso foco é mostrar a parte mais básica e entender o funcionamento.
Client-side
Com nosso servidor concluido e rodando, vamos passar para a parte de client-side de nossa aplicação de chat. Vamos ao js.js.
Primeiramente, inicializaremos o socket.io e criaremos uma variável ready, setada como false. Esta variável será responsável por indicar se o usuário já informou ou não o seu nickname.
Com esta implementação, já conseguimos disparar o evento connection em nosso servidor. Porém, precisamos fazer com que o servidor receba a informação cada vez que um novo usuário entrar na sala informando o seu nickname.
A função jQuery acima captura a submissão do formulário de nickname, fecha a tela de seleção de nick, mostra a tela de chat, seta a variável ready para true e executa um comando de socket, o socket.emit, que informa para o nosso servidor que um novo usuário acabou de entrar na sala.
Nada irá acontecer, pois ainda não temos o receptor do evento update, que está sendo disparado no nosso servidor, então vamos criá-lo:
Este código fará com que, a cada vez que o servidor emitir um update, o jQuery adicione uma nova linha no chat com a mensagem retornada.
Agora, iremos fazer com que nossa aplicação envie as mensagens ao servidor a cada vez que o cliente apertar o enter no input de texto:
E, para concluir, precisamos fazer com que o socket.io observe todas as mensagens referente ao chat em si, e adicione à DOM:
Conclusão
Na minha opinião, as sockets são uma das melhores funcionalidades do HTML5, e possuem uma infinidade de aplicação. O ganho de performance é espetacular se bem aplicado, uma vez que evita o uso de requisições HTTP em aplicações onde a necessidade de atualização é grande (baixa latência).
Disponibilizei o código do tutorial no github para quem se interessar, e estou aberto a tirar dúvidas.