Diferença entre Web Sockets e Socket.IO



Bom dia amigos

Os soquetes da Web e o Socket.IO são provavelmente os dois meios mais comuns de comunicação em tempo real (a seguir denominada comunicação ao vivo). Mas como eles diferem?

Ao criar um aplicativo para comunicação ao vivo, chega um momento em que você precisa escolher uma ferramenta para a troca de dados entre o cliente e o servidor. Os soquetes da Web e o Socket.IO são os meios mais populares de comunicação ao vivo na Web moderna. Qual escolher? Qual a diferença entre essas tecnologias? Vamos descobrir.

Soquetes da Web


Falando em soquetes da web, entendemos o protocolo de comunicação na web, que representa um canal de comunicação full-duplex através de uma conexão TCP simples. Simplificando, essa tecnologia permite estabelecer comunicação entre o cliente e o servidor com um custo mínimo, permitindo criar aplicativos que utilizam todas as vantagens da comunicação ao vivo.

Por exemplo, imagine que você está criando um bate-papo: você precisa receber e enviar dados o mais rápido possível, certo? Os soquetes da Web funcionam bem com isso! Você pode abrir uma conexão TCP e mantê-la aberta pelo tempo que for necessário.

Soquetes da Web apareceram em 2010 no Google Chrome 4, a primeira RFC ( 6455 ) foi publicada em 2011.

Os soquetes da Web são usados ​​nos seguintes casos:

  • Bate-papo
  • Jogos multiplayer
  • Edição colaborativa
  • Feeds sociais (notícias)
  • Aplicativos baseados em localização

etc.

Socket.io


O Socket.IO é uma biblioteca JavaScript baseada (escrita na parte superior) em soquetes da Web ... e outras tecnologias. Ele usa soquetes da Web quando disponíveis, ou tecnologias como Flash Socket, AJAX Long Polling, AJAX Multipart Stream, quando os soquetes da Web não estão disponíveis. Uma analogia fácil é a comparação da API de busca e do Axios.

Diferença entre Web Sockets e Socket.IO


As principais vantagens do Socket.IO são as seguintes:

  • -, Socket.IO . , . . -, .
  • - . Socket.IO .
  • , Socket.IO () .
  • Socket.IO .
  • Socket.IO .

Pode parecer que o Socket.IO seja a melhor ferramenta para comunicação ao vivo. No entanto, existem várias situações em que é melhor usar soquetes da web.

Em primeiro lugar, os soquetes da web são suportados por todos os navegadores modernos. Portanto, você raramente precisa do suporte de outras tecnologias fornecidas pelo Socket.IO.

Se falamos de tráfego de rede, os soquetes da Web enviam apenas duas solicitações:

  • GET para obter a página HTML
  • ATUALIZAÇÃO para conectar a soquetes da web

Isso permite que você se conecte ao servidor. E o Socket.IO?

  • GET para obter a página HTML
  • Biblioteca cliente Socket.IO ( 207kb )
  • Três solicitações longas do Ajax para pesquisas
  • ATUALIZAÇÃO para conectar a soquetes da web

No mundo do JS, 207kb é muito. Que uso irracional do tráfego de rede!

No npm, existe um pacote "websocket-vs-socket.io" que permite comparar o tráfego de rede dessas tecnologias:

Tráfego de rede de soquete da Web:




Tráfego de rede do Socket.IO:




A diferença é óbvia!

Escrevendo um código


Servidor de soquete da web simples


Em nosso programa no Node.js, criaremos um servidor em execução na porta 3001. Cada vez que o cliente se conectar, atribuiremos a ele um ID exclusivo. Ao enviar uma mensagem para o cliente, notificaremos o sucesso: [<client-id>]: <message>

const WebSocket = require('ws')
const UUID = require('uuid')
const wss = new WebSocket.Server({ port: 3001 })

wss.on('connection', ws => {
  ws.id = UUID()

  ws.on('message', message => {
    ws.send(`[${ws.id}]: ${message}`)
  })
})

Bem! Mas e se quisermos enviar uma mensagem para cada cliente conectado? Os soquetes da Web não oferecem suporte para correspondência por padrão. Isso pode ser implementado da seguinte maneira:

const WebSocket = require("ws")
const UUID      = require("uuid")
const wss       = new WebSocket.Server({ port: 3001 })

function broadcast(clientId, message) {
  wss.clients.forEach(client => {
    if(client.readyState === WebSocket.OPEN) {
      client.send(`[${clientId}]: ${message}`)
    }
  })
}

wss.on('conection', ws => {
  ws.id = UUID()
  ws.on('message', message => broadcast(ws.id, message))
})

Simples e facilmente! Como você pode ver, o WebSocket.Server mantém registros de cada cliente conectado, para que possamos iterar e enviar uma mensagem para todos. Você pode testar o código em um computador (MacOS) ou em um navegador (Chrome) .

Servidor simples no Socket.IO


Não foi difícil. O Socket.IO pode torná-lo ainda mais fácil? Como escrevemos o mesmo servidor no Socket.IO?

const io = require('socket.io')
const server = io.listen(3002)

server.on('connection', socket => {
  socket.on('message', message => {
    socket.emit(`[${socket.id}]: ${message}`)
    socket.broadcast.emit(`[${socket.id}]: ${message}`)
  })
})

O código é quase metade mais curto! Como você pode ver, o método de transmissão não envia uma notificação ao remetente, por isso somos forçados a fazer isso manualmente.

Há um problema: o código não pode ser testado em um cliente de soquete da Web comum. Isso se deve ao fato de que, conforme observado anteriormente, o Socket.IO não usa soquetes da Web puros, mas muitas tecnologias para oferecer suporte a todos os possíveis clientes. Então, como testamos seu desempenho?

// head
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2.3.0/dist/socket.io.slim.js"></script>

// body
<script>
  ioClient = io.connect('http://localhost:3002')
  ioClient.on('connect', socket => {
    ioClient.send('hello world')
    ioClient.on('message', msg => console.log(msg))
  })
</script>

Você deve usar um cliente especial. No exemplo acima, nós o carregamos da CDN. Esse cliente nos permite realizar testes rápidos (sujos) no navegador.

Como você pode ver, nossos exemplos não são muito diferentes. No entanto, se falarmos sobre compatibilidade, deve-se lembrar que o Socket.IO trabalha com sua própria biblioteca e não pode ser usado para fins não relacionados ao desenvolvimento da web. Ao mesmo tempo, os soquetes da Web podem ser usados ​​para resolver uma ampla variedade de tarefas, como comunicação P2P, troca de dados em tempo real entre servidores, etc.

Em uma nota


Escala horizontal. Digamos que seu bate-papo ganhou popularidade e você precisa adicionar outro servidor e balanceador de carga para processar solicitações. Bem, se você abrir a conexão com o “servidor 1”, o balanceador o alternará para o “servidor 2”, você receberá o erro: “Erro durante o handshake do WebSocket: Código de resposta inesperado: 400”. O Socket.IO resolve esse problema usando cookies (ou roteando conexões com base nos endereços de origem), e os soquetes da Web não possuem esse mecanismo.
Atuação. Como observado anteriormente, o Socket.IO fornece várias camadas abstratas acima da camada de transporte dos soquetes da Web. Além disso, o empacotamento de dados no formato JSON é usado aqui, portanto, não há possibilidade de enviar dados binários para o servidor (e vice-versa). Se você precisar dessa funcionalidade, precisará "conjurar" o código da biblioteca para garantir o comportamento desejado. Com soquetes da web, esses problemas não surgem.

Então o que escolher?


Você decide.

O Socket.IO facilita a vida, você não precisa se preocupar com problemas relacionados ao balanceamento de carga, desconexão ou envio de mensagens ... mas precisa dessa funcionalidade? A biblioteca do cliente Socket.IO pesa mais do que os pacotes React, Redux e React-Redux combinados. Tem certeza de que não pode se limitar a soquetes da web?

Outro aspecto importante a ser lembrado é que, ao usar o Socket.IO no lado do servidor, a maior parte do código será escrita nas abstrações fornecidas por esta biblioteca. Se você precisar reescrever os microsserviços Node.js. em Go, Elixir, Java ou outra linguagem de programação, precisará reescrever quase toda a lógica. Por exemplo, para enviar mensagens para o Socket.IO, o método "broadcast" é usado (implementado manualmente em soquetes da Web); portanto, ao refatorar, você precisará entender como esse método funciona. Os soquetes da Web devem ser preferidos nesse caso, pois são mais fáceis de adaptar.

Obrigado pela atenção.

All Articles