Equívocos
Existem alguns conceitos errados comuns sobre o WebSocket e o Socket.IO:
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.
O segundo equívoco é que o WebSocket não é amplamente suportado nos navegadores. Veja abaixo para mais informações.
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:
- Própria página HTML
- 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:
- a própria página HTML
- JavaScript do Socket.IO (180 kilobytes)
- primeira solicitação AJAX de sondagem longa
- segundo pedido AJAX de sondagem longa
- terceira solicitação AJAX de sondagem longa
- atualização de conexão para WebSocket
Screenshots
Resultados do WebSocket que obtive no localhost:
Resultados do Socket.IO que obtive no localhost:
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:
Consulte http://caniuse.com/websockets para obter informações atualizadas.