Diferencias entre socket.io y websockets

¿Cuáles son las diferencias entre socket.io y websockets en node.js?
¿Son ambas tecnologías de empuje del servidor? Las únicas diferencias que sentí fueron,

  1. socket.io me permitía enviar/emitir mensajes especificando un nombre de evento.

  2. En el caso de socket.io un mensaje del servidor llegará a todos los clientes, pero para lo mismo en websockets me vi obligado a mantener un array de todas las conexiones y hacer un bucle a través de él para enviar mensajes a todos los clientes.

Además, me pregunto por qué los inspectores web (como Chrome/firebug/fiddler) no son capaces de captar estos mensajes (de socket.io/websocket) del servidor.

Por favor, aclare esto.

Comentarios sobre la pregunta (2)

Conceptos erróneos

Hay algunos conceptos erróneos comunes con respecto a WebSocket y Socket.IO:

  1. El primer concepto erróneo es que el uso de Socket.IO es significativamente más fácil que el uso de WebSocket, lo cual no parece ser el caso. Vea los ejemplos siguientes.

  2. El segundo concepto erróneo es que WebSocket no está ampliamente soportado en los navegadores. Ver más abajo para más información.

  3. La tercera idea errónea es que Socket.IO rebaja la conexión como un recurso en los navegadores más antiguos. En realidad asume que el navegador es antiguo e inicia una conexión AJAX con el servidor, que se actualiza posteriormente en los navegadores que soportan WebSocket, después de que se intercambie algo de tráfico. Ver abajo para más detalles.

Mi experimento

Escribí un módulo npm para demostrar la diferencia entre WebSocket y Socket.IO:

Es un ejemplo simple de código del lado del servidor y del lado del cliente - el cliente se conecta al servidor usando WebSocket o Socket.IO y el servidor envía tres mensajes en intervalos de 1s, que son agregados al DOM por el cliente.

Del lado del servidor

Compara el ejemplo del lado del servidor usando WebSocket y Socket.IO para hacer lo mismo en una aplicación Express.js:

Servidor WebSocket

Ejemplo 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');

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

Servidor Socket.IO

Ejemplo 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');

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

Cliente

Compara el ejemplo del lado del cliente de usar WebSocket y Socket.IO para hacer lo mismo en el navegador:

Cliente WebSocket

Ejemplo de cliente WebSocket usando vanilla JavaScript:

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); });

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

Cliente Socket.IO

Ejemplo de cliente Socket.IO usando JavaScript:

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); });

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

Tráfico en la red

Para ver la diferencia en el tráfico de red puedes ejecutar mi prueba. Aquí están los resultados que obtuve:

Resultados de WebSocket

2 peticiones, 1.50 KB, 0.05 s

De esas 2 peticiones:

  1. Página HTML propiamente dicha
  2. actualización de la conexión a WebSocket

(La solicitud de actualización de la conexión es visible en las herramientas del desarrollador con una respuesta 101 Switching Protocols).

Resultados de Socket.IO

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

De esas 6 peticiones:

  1. la propia página HTML
  2. Socket.IO's JavaScript (180 kilobytes)
  3. la primera petición AJAX de sondeo largo
  4. segunda petición AJAX de sondeo largo
  5. tercera petición AJAX de sondeo largo
  6. actualización de la conexión a WebSocket

Capturas de pantalla

Resultados de WebSocket que obtuve en localhost:

[]

Resultados de Socket.IO que obtuve en localhost:

[]

Pruebe usted mismo

Inicio rápido:

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

Abre http://localhost:3001/ en tu navegador, abre las herramientas de desarrollo con Shift+Ctrl+I, abre la pestaña de Red y recarga la página con Ctrl+R para ver el tráfico de red de la versión WebSocket.

Abre http://localhost:3002/ en tu navegador, abre las herramientas de desarrollo con Shift+Ctrl+I, abre la pestaña Red y recarga la página con Ctrl+R para ver el tráfico de red para la versión Socket.IO.

Para desinstalar:

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

Compatibilidad con el navegador

A partir de junio de 2016, WebSocket funciona en todo, excepto en Opera Mini, incluyendo IE superior a 9.

Esta es la compatibilidad de navegadores de WebSocket en Can I Use a partir de junio de 2016:

[]

Consulte http://caniuse.com/websockets para obtener información actualizada.

Comentarios (6)
Solución

Sus ventajas son que simplifica el uso de WebSockets tal y como lo has descrito en el punto 2, y probablemente lo más importante es que proporciona fail-overs a otros protocolos en el caso de que WebSockets no esté soportado en el navegador o el servidor. Yo evitaría usar WebSockets directamente a menos que estés muy familiarizado con los entornos en los que no funcionan y seas capaz de trabajar alrededor de esas limitaciones.

Esta es una buena lectura sobre WebSockets y Socket.IO.

http://davidwalsh.name/websocket

Comentarios (10)

Voy a proporcionar un argumento contra el uso de socket.io.

Creo que usar socket.io sólo porque tiene fallbacks no es una buena idea. Deje que IE8 RIP.

En el pasado ha habido muchos casos en los que las nuevas versiones de NodeJS han roto socket.io. Puedes consultar estas listas para ver ejemplos... https://github.com/socketio/socket.io/issues?q=install+error

Si vas a desarrollar una aplicación para Android o algo que necesita trabajar con tu aplicación existente, probablemente estarías bien trabajando con WS de inmediato, socket.io podría darte algunos problemas allí...

Además el módulo WS para Node.JS es increíblemente sencillo de usar.

Comentarios (0)

Usar Socket.IO es básicamente como usar jQuery - si quieres apoyar a los navegadores más antiguos, necesitas escribir menos código y la biblioteca proveerá de respaldos. Socket.io utiliza la tecnología de los webckets si está disponible, y si no, comprueba el mejor tipo de comunicación disponible y lo utiliza.

Comentarios (0)

Socket.IO usa WebSocket y cuando WebSocket no está disponible usa algo de respaldo para hacer conexiones en tiempo real.

Comentarios (0)

Incluso si los navegadores modernos soportan WebSockets ahora, creo que no hay necesidad de tirar SocketIO y todavía tiene su lugar en cualquier proyecto de hoy en día. Es fácil de entender, y personalmente, aprendí cómo funcionan los WebSockets gracias a SocketIO.

Como se ha dicho en este tema, hay un montón de librerías de integración para Angular, React, etc. y tipos de definición para TypeScript y otros lenguajes de programación.

El otro punto que añadiría a las diferencias entre Socket.io y WebSockets es que la agrupación con Socket.io no es gran cosa. Socket.io ofrece [Adaptadores][1] que pueden ser usados para enlazarlo con Redis para mejorar la escalabilidad. Tienes [ioredis][2] y [socket.io-redis][3] por ejemplo.

Sí, lo sé, [SocketCluster][4] existe, pero eso's fuera de tema.

[1]: https://socket.io/docs/using-multiple-nodes/#passing-events-between-nodes [2]: https://github.com/luin/ioredis [3]: https://github.com/socketio/socket.io-redis [4]: https://github.com/SocketCluster/socketcluster

Comentarios (0)