Socket.IO - Primeiros passos
Tags: braziliandevs, node, socketio, tutorial
Published: 2023-02-24 18:19:36

<p>Desde o início do desenvolvimento web, muitas pessoas desenvolvedoras enfretaram diversos impedimentos relacionados ao disparo de eventos. Antes mesmo dos diversos frameworks que gerenciam o estado das aplicações, as mesmas que agarravam apenas ao XMLHttpRequest para fazer requisições assíncronas às APIs próprias e de terceiros. </p> <p>Entretanto, em algumas aplicações, queremos controlar estados e gerar nossos próprios eventos criando uma integração entre cliente e servidor que não necessita exclusivamente de uma API. Para isso, o <em><strong>Socket.IO</strong></em> pode nos ajudar muito. </p> 

<h3>Mas, o que é o Socket.IO?</h3> 
<p>O socket.IO é uma biblioteca que permite comunicação bidirecional e baseada em eventos entre um servidor e um cliente e o melhor, com baixa latência. Construído sobre o WebSocket, o mesmo permite reconexão e o envio de pacotes entre cliente e servidor com o menor custo para o seu servidor.</p><p> O socket.IO tem suporte para diversas linguagens:</p>
<ul><li>Javascript</li><li>Java</li><li>Python</li><li>Golang</li><li>.NET</li><li>C++</li><li>Swift</li><li>Rust</li><li>Kotlin ...</li></ul>

<p>Visto isso, vamos a uma pequena introdução utilizando <strong>Node.JS</strong>. O exemplo mais simples que temos para a utilização do socket.IO é a criação de uma sala de bate-papo. Isso porque temos uma aplicação de troca de mensagens entre diversos clientes em tempo real, cuja comunicação deve passar pelo servidor, seja apenas para gerenciamento ou para salvar em alguma base de dados. </p><p>Mas não precisamos salvar em uma base de dados para fornecer uma comunicação em tempo real. Temos apenas que criar uma comunicação baseada em eventos com o Socket.IO</p>

<h2>Vamos ao código</h2>
<h3>Server-side</h3>
<p>Primeiro, criamos um server http para o nosso back-end</p>

```js
// server.js
const http = require('http');
server = http.createServer(app); 
```
<p>Depois, vamos criar um novo arquivo chamado Room.js, onde deixaremos todos os nossos eventos do socket.IO e vamos dizer ao nosso server que, ao se conectar, nossos eventos estarão sem gerenciados nesse arquivo.</p>


```js
// server.js
const io = require('socket.io')(server);
const Room = require('./Room')(io);
server.listen(port, () => console.log("Chat online"));
```

 <p>Podemos agora criar o arquivo Room.js para centralizar nossos eventos. E nesse momento, vamos começar a trabalhar de fato com o Socket.IO utilizando apenas dois métodos: <strong>on</strong> e <strong>emit</strong>.</p>
    
   <p>O método <strong>on</strong> é o método que diz qual é o evento que você deseja receber e quais as informações e códigos relacionados ao mesmo. É basicamente o método que serve como sua caixa de entrada.</p>
    
   <p>O método <strong>emit</strong>, ao contrário do on, é o método que dispara uma mensagem para algum evento e envia as informações. É basicamente o método que serve como caixa de saída. </p>
   
   <p> Relacionando os dois métodos, você pode ter os dois tanto no lado cliente como no lado servidor e para exemplificar, se você tem no server-side o método on e no client-side o método emit, temos </p>
   
```js
   // server-side
   socket.on('mensagem', function(texto) {
       console.log(texto);
   });
```

```js
   // client-side
   socket.emit('mensagem', 'Olá pessoas desenvolvedoras do tabnews');
```

   <p>Isso quer dizer que no momento que disparássemos o código do cliente, seja por um botão ou qualquer outra interação qualquer, teríamos um print no back-end da mensagem <strong>Olá pessoas desenvolvedoras do tabnews</strong></p>
   
   <p>E como o socket.IO sabe onde direcionar?</p>
   
   <p>Graças ao nome do evento, <strong>mensagem</strong>, que você escolheu. Enquanto nos métodos emit, temos como parâmetro o nome do evento e alguma informação, nos métodos on temos o mesmo nome de evento e uma função que receberá como parâmetro, todos os outros parâmetros restantes do método emit. Legal né?</p>.

<p>Agora, alguns conhecimentos mais avançados. No socket.io, temos o conceito de salas. Na qual cada client pode ser direcionado a uma sala e as mensagens podem ser direcionadas tanto a uma sala como a algun cliente específico. Dessa forma, temos mais 03 métodos interessantes: join, leave e to.</p>

<p>O método <strong>join</strong> serve para direcionar um cliente a alguma sala. A construção do mesmo é apenas indicar qual o nome da sala. Então temos:</p>

```js
socket.join(nomeDaSala);
```

<p>O método <strong>leave</strong> serve para fazer o oposto do método join, ou seja, tirar o cliente de alguma sala. Então temos:</p>

```js
socket.leave(nomeDaSala);
```


<p>O método <strong>to</strong>, por último serve para enviar uma mensagem em determinada sala. Ele se une ao método emit mas garantindo que apenas os clientes associados à determinada sala recebam a mensagem. Então temos:</p>

```js
socket.to(nomeDaSala).emit('mensagem', 'Olá pessoas desenvolvedoras do tabnews');
```
    
 <p>O resto do funcionamento é o mesmo. Trazendo esse contexto para o nosso <em><strong>Room.js</strong></em>, temos o seguinte bloco de código</p>
 
 ```js
 function listen(socket){
    const io = _io;
    
    socket.on('join', function(sala){
        socket.join(sala);
    });

    socket.on('leave', function(sala){
        socket.leave(sala);
    });

    socket.on('mensagem', function(Sala, Mensagem){
        socket.to(Sala).emit('msg', Mensagem);
    });
 }

module.exports = function(io){
    _io = io;
    return {listen};
};
```

<h3>Client-side</h3>

<p>Agora para o nosso lado cliente, temos basicamente, todos os mesmos eventos mas com construções inversas. Onde temos on de um lado, temos emit do outro.</p>

```js
 socket.on('msg', function(Mensagem){
     // Código relacionado a receber uma mensagem no cliente.
 });
 
 socket.emit("join",nomeDaSala);
 
 socket.emit("leave", nomeDaSala);
 
 ```
 
 <h3>Repositório completo</h3>
 
 <p>Para facilitar na absorção, deixei um repositório pronto como uma sala básica de bate-papo com socket.IO. Não utilizei muitos frameworks e para ser absorvido, independentemente da tecnologia de front-end que você utiliza, deixei com JQuery que é mais simples de entender.</p>
 
 ![Bate-Papo](https://raw.githubusercontent.com/Danilo-Oliveira-Silva/Chat/main/chat-print-geral.png)
 
 [O repositório pode ser encontrado aqui.](https://github.com/Danilo-Oliveira-Silva/Chat)
 
 <h3>O que mais posso fazer com Socket.IO</h3>
 
 <p>Apesar da sala de bate-papo ser o exemplo mais didático da utilização dessa biblioteca, podemos fazer inúmeras aplicações com Socket.IO</p>
 
 <ul>
    <li>Jogos online</li>
    <li>SIP Server (VoIP)</li>
    <li>WebRTC ...</li>
 </ul>
 
 <p>Inclusive, com o Socket.IO, podemos fazer uns clones funcionais bem interessantes, como o clone de softwares como: </p>
  <ul>
    <li>Discord</li>
    <li>Zoom</li>
    <li>Twitch</li>
 </ul>
 <p>Mas esses clones e a explicação de WebRTC, caso gostem desse conteúdo, deixamos para uma próxima.</p>
 <p>Espero que gostem. Bons estudos</p>