Diferenças entre socket.io e websockets

459

Quais são as diferenças entre socket.io e websockets no node.js?
Ambas são tecnologias push de servidor? As únicas diferenças que senti foram,

  1. socket.io me permitiu enviar / emitir mensagens especificando um nome de evento.

  2. No caso do socket.io, uma mensagem do servidor chegará a todos os clientes, mas, para o mesmo nos websockets, fui forçado a manter uma matriz de todas as conexões e percorrê-lo para enviar mensagens a todos os clientes.

Além disso, eu me pergunto por que os inspetores da Web (como o Chrome / firebug / fiddler) não conseguem capturar essas mensagens (do socket.io/websocket) do servidor?

Por favor, esclareça isso.

Vivek Mohan
fonte
6
Sobre o motivo pelo qual os inspetores da Web não capturam o tráfego: consulte Como exibir o conteúdo da solicitação do WS / WSS Websocket usando o Firebug ou outro?
treaz
1
@treaz você não precisa do Firebug ou de qualquer outra coisa. As ferramentas do Chrome mostram conexões WS na guia redes.
Verifique isso também (não tenho certeza se este é o mais recente) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Respostas:

326

Suas vantagens são que simplifica o uso do WebSockets conforme descrito em # 2 e, provavelmente, o mais importante, fornece failover para outros protocolos no caso de o WebSockets não ser suportado no navegador ou servidor. Eu evitaria usar o WebSockets diretamente, a menos que você esteja familiarizado com os ambientes em que eles não funcionam e seja capaz de contornar essas limitações.

Esta é uma boa leitura sobre WebSockets e Socket.IO.

http://davidwalsh.name/websocket

Timothy Strimple
fonte
63
O Socket.IO não é construído sobre WebSockets, apenas usa essa tecnologia quando está disponível.
M12
24
Diferença semântica e expliquei isso no restante da resposta, mas atualizei a resposta para refletir isso.
Timothy Strimple
1
@moka, pelas suas palavras, posso concluir que a seguinte declaração está errada? Socket.IO é realmente mais do que uma camada sobre WebSockets.
Pulak Kanti Bhattacharyya
3
@PulakKantiBhattacharyya, você poderia especificar a qual afirmação exatamente está se referindo? O Socket.IO é muito mais do que apenas uma camada acima do WebSockets, possui diferentes semânticas (marca as mensagens com o nome) e realiza failovers em diferentes protocolos, além de possuir um mecanismo de pulsação. Mais do que isso anexa IDs a clientes no lado do servidor e muito mais. Portanto, não é apenas um invólucro, é uma biblioteca com todos os recursos. Na verdade, ele não tem sido bem suportado nos últimos anos, então eu recomendaria usar o SockJS, que é uma alternativa muito melhor e mais mantida ao Socket.IO.
moka
4
@moka Há um mês, eu teria concordado com você. O Socket.io 1.0 já está disponível e está sendo atualizado.
Timothy Strimple
538

Equívocos

Existem alguns conceitos errados comuns sobre o WebSocket e o Socket.IO:

  1. O primeiro equívoco é que usar o Socket.IO é significativamente mais fácil do que usar o WebSocket, o que não parece ser o caso. Veja exemplos abaixo.

  2. O segundo equívoco é que o WebSocket não é amplamente suportado nos navegadores. Veja abaixo para mais informações.

  3. O terceiro equívoco é que o Socket.IO rebaixa a conexão como um substituto em navegadores mais antigos. Na verdade, ele assume que o navegador é antigo e inicia uma conexão AJAX com o servidor, que é posteriormente atualizada em navegadores que suportam o WebSocket, depois que algum tráfego é trocado. Veja abaixo para detalhes.

Minha experiência

Eu escrevi um módulo npm para demonstrar a diferença entre WebSocket e Socket.IO:

É um exemplo simples de código do lado do servidor e do cliente - o cliente se conecta ao servidor usando o WebSocket ou o Socket.IO e o servidor envia três mensagens em intervalos de 1s, que são adicionadas ao DOM pelo cliente.

Lado do servidor

Compare o exemplo do servidor do uso do WebSocket e Socket.IO para fazer o mesmo em um aplicativo Express.js:

Servidor WebSocket

Exemplo de servidor WebSocket usando Express.js:

var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
  console.error('websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');

Fonte: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

Servidor Socket.IO

Exemplo de servidor Socket.IO usando Express.js:

var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
  console.error('socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');

Fonte: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

Lado do cliente

Compare o exemplo do lado do cliente de usar WebSocket e Socket.IO para fazer o mesmo no navegador:

Cliente WebSocket

Exemplo de cliente WebSocket usando JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });

Fonte: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

Cliente Socket.IO

Exemplo de cliente Socket.IO usando JavaScript vanilla:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });

Fonte: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

Tráfego de rede

Para ver a diferença no tráfego de rede, você pode executar meu teste . Aqui estão os resultados que obtive:

Resultados do WebSocket

2 pedidos, 1,50 KB, 0,05 s

Desses 2 pedidos:

  1. Própria página HTML
  2. atualização de conexão para WebSocket

(A solicitação de atualização da conexão é visível nas ferramentas do desenvolvedor com uma resposta 101 Switching Protocols.)

Resultados do Socket.IO

6 pedidos, 181,56 KB, 0,25 s

Desses 6 pedidos:

  1. a própria página HTML
  2. JavaScript do Socket.IO (180 kilobytes)
  3. primeira solicitação AJAX de sondagem longa
  4. segundo pedido AJAX de sondagem longa
  5. terceira solicitação AJAX de sondagem longa
  6. atualização de conexão para WebSocket

Screenshots

Resultados do WebSocket que obtive no localhost:

Resultados do WebSocket - módulo websocket-vs-socket.io

Resultados do Socket.IO que obtive no localhost:

Resultados do Socket.IO - módulo websocket-vs-socket.io

Teste-se

Começo rápido:

# Install:
npm i -g websocket-vs-socket.io
# Run the server:
websocket-vs-socket.io

Aberto http: // localhost: 3001 / no seu navegador, abra as ferramentas de desenvolvedor com Shift + Ctrl + I, abra a guia Rede e recarregue a página com Ctrl + R para ver o tráfego de rede da versão WebSocket.

Abra http: // localhost: 3002 / no seu navegador, abra as ferramentas de desenvolvedor com Shift + Ctrl + I, abra a guia Rede e recarregue a página com Ctrl + R para ver o tráfego de rede da versão Socket.IO.

Para desinstalar:

# Uninstall:
npm rm -g websocket-vs-socket.io

Compatibilidade do navegador

Em junho de 2016, o WebSocket funcionava em tudo, exceto no Opera Mini, incluindo o IE superior a 9.

Esta é a compatibilidade do navegador do WebSocket no Can I Use a partir de junho de 2016:

insira a descrição da imagem aqui

Consulte http://caniuse.com/websockets para obter informações atualizadas.

rsp
fonte
23
Então, basicamente, o que você está dizendo é que, o websocket é melhor que o socket.io?
Jack Moscovi
42
@JackMoscovi Eu não diria que o WebSocket é necessariamente melhor. Tudo depende dos requisitos. As vantagens do WebSocket são que ele é um padrão da Web (primeiro no W3C e whatwg, agora no IETF, com uma RFC publicada há 5 anos), é muito leve porque é suportado nativamente pelos navegadores, mas o suporte ao navegador enquanto é bom é não é universal. O Socket.IO suporta mais navegadores e tem mais funcionalidades, mas também vem com algumas despesas gerais. Às vezes um é melhor, às vezes o outro. É como escolher entre querySelectorAll e jQuery - a resposta não é sempre a mesma
RSP
20
Ótima resposta aqui !! Parece-me que socket.io não é mais necessário em muitos casos ... Consulte também este excelente artigo! medium.com/@ivanderbyl/…
Alvaro
4
@rsp Acho que esses exemplos não são funcionalmente equivalentes? O Socket-io lida com coisas como a reconexão automática quando interrompido (o que acontece em dispositivos móveis) e acho que existem preocupações de segurança em torno daquilo que é tratado para você? Seus exemplos simples de WS, embora funcionalmente equivalentes, não possuem essas propriedades.
mindplay.dk
28
Comparação muito boa. No entanto, vale a pena notar que o Socket.io adiciona espaçamento de nome de sala, muitos detalhes de conexão, muitos detalhes de registro e há muitas bibliotecas de integração para o Socket.IO com Angular, Vue, React e outras. Mais importante, você pode desativar a pesquisa longa do Ajax e conectar-se diretamente via WebSocket como uma conexão WebSocket bruta. Dessa forma, você obtém tudo, exceto a biblioteca de 180kb, como iguais. Usar o WebSocket diretamente é doloroso, a menos que você precise apenas do mínimo. Eliminar salas e acesso ao IP da comunidade é assustador para as empresas.
Nick Steele
30

Vou fornecer um argumento contra o uso do socket.io.

Eu acho que usar socket.io apenas porque tem fallbacks não é uma boa idéia. Deixe o IE8 rasgar.

No passado, houve muitos casos em que novas versões do NodeJS quebraram o socket.io. Você pode verificar essas listas para obter exemplos ... https://github.com/socketio/socket.io/issues?q=install+error

Se você desenvolver um aplicativo para Android ou algo que precise trabalhar com o aplicativo existente, provavelmente estará bem trabalhando com o WS imediatamente, o socket.io poderá lhe dar alguns problemas ...

Além disso, o módulo WS para Node.JS é incrivelmente simples de usar.

Victorio Berra
fonte
O que você sugere que usamos para interagir com mysql -> express.js / fastify.js ou Node.js diretamente ... Para construir android e ios bate-papo aplicativos
DragonFire
25

Usar o Socket.IO é basicamente como usar o jQuery - você deseja oferecer suporte a navegadores mais antigos, precisa escrever menos código e a biblioteca fornecerá fallbacks. O Socket.io usa a tecnologia websockets, se disponível, e se não, verifica o melhor tipo de comunicação disponível e o utiliza.

Dev Agrawal
fonte
3

Mesmo que os navegadores modernos ofereçam suporte ao WebSockets agora, acho que não há necessidade de jogar fora o SocketIO e ele ainda tem seu lugar em qualquer projeto atual. É fácil de entender e, pessoalmente, aprendi como o WebSockets funciona graças ao SocketIO.

Como dito neste tópico, existem várias bibliotecas de integração para tipos de definição Angular, React etc., e de definição para TypeScript e outras linguagens de programação.

O outro ponto que eu acrescentaria às diferenças entre o Socket.io e o WebSockets é que o clustering com o Socket.io não é um grande problema. O Socket.io oferece adaptadores que podem ser usados ​​para vinculá-lo ao Redis para aprimorar a escalabilidade. Você possui ioredis e socket.io-redis, por exemplo.

Sim, eu sei, o SocketCluster existe, mas isso é fora de tópico.

Maxime Lafarie
fonte
2

O Socket.IO usa o WebSocket e, quando o WebSocket não está disponível, usa algo de fallback para fazer conexões em tempo real.

Nitin.
fonte
0

https://socket.io/docs/#What-Socket-IO-is-not (com minha ênfase )

O que o Socket.IO não é

O Socket.IO NÃO é uma implementação do WebSocket. Embora o Socket.IO realmente use o WebSocket como transporte quando possível, ele adiciona alguns metadados a cada pacote: o tipo de pacote, o espaço para nome e a identificação do pacote quando uma confirmação de mensagem é necessária. É por isso que um cliente WebSocket não poderá se conectar com êxito a um servidor Socket.IO , e um cliente Socket.IO também não poderá se conectar a um servidor WebSocket . Por favor, veja a especificação do protocolo aqui .

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');
Ken Lin
fonte