Diferencias entre socket.io y websockets

459

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

  1. socket.io me permitió 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 por lo mismo en websockets me vi obligado a mantener un conjunto de todas las conexiones y recorrerlo para enviar mensajes a todos los clientes.

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

Por favor aclara esto.

Vivek Mohan
fuente
66
En cuanto a por qué los inspectores web no atrapan el tráfico: vea ¿Cómo ver el contenido de la solicitud WS / WSS Websocket usando Firebug u otro?
treaz
1
@treaz no necesitas Firebug ni nada más. Los devtools de Chrome muestran conexiones WS en la pestaña de redes.
Compruebe esto también (no estoy seguro de si es lo último) - educba.com/websocket-vs-socket-io
Manohar Reddy Poreddy

Respuestas:

326

Sus ventajas son que simplifica el uso de WebSockets como lo describió en el n. ° 2, y probablemente lo más importante es que proporciona fallas a otros protocolos en caso de que WebSockets no sean compatibles con el navegador o el servidor. Evitaría usar WebSockets directamente a menos que esté muy familiarizado con los entornos en los que no funcionan y que sea capaz de evitar esas limitaciones.

Esta es una buena lectura tanto en WebSockets como en Socket.IO.

http://davidwalsh.name/websocket

Timothy Strimple
fuente
63
Socket.IO no está construido sobre WebSockets, solo usa esta tecnología cuando está disponible.
moka
24
Diferencia semántica y lo expliqué en el resto de la respuesta, pero he actualizado la respuesta para reflejar esto.
Timothy Strimple
1
@moka, según tus palabras, ¿puedo concluir que la siguiente afirmación es incorrecta? Socket.IO es en realidad más que una capa sobre WebSockets.
Pulak Kanti Bhattacharyya
3
@PulakKantiBhattacharyya, ¿podría especificar a qué afirmación se refiere exactamente? Socket.IO es mucho más que una capa por encima de WebSockets, tiene una semántica diferente (marca los mensajes con el nombre) y realiza failovers a diferentes protocolos, además tiene un mecanismo de latido. Más a eso adjunta ID's a clientes en el lado del servidor, y más. Por lo tanto, no es solo un contenedor, es una biblioteca con todas las funciones. De hecho, no se ha admitido bien en los últimos años, por lo que recomendaría usar SockJS, que es una alternativa mucho mejor y más mantenida a Socket.IO.
moka
44
@moka Hace un mes hubiera estado de acuerdo contigo. Socket.io 1.0 ya está disponible y está recibiendo actualizaciones.
Timothy Strimple
538

Conceptos erróneos

Hay algunas ideas falsas comunes con respecto a WebSocket y Socket.IO:

  1. La primera idea errónea es que usar Socket.IO es significativamente más fácil que usar WebSocket, lo que no parece ser el caso. Ver ejemplos a continuación.

  2. El segundo error es que WebSocket no es ampliamente compatible con los navegadores. Vea abajo para más información.

  3. El tercer concepto erróneo es que Socket.IO degrada la conexión como una alternativa en los navegadores más antiguos. En realidad, supone que el navegador es antiguo e inicia una conexión AJAX con el servidor, que luego se actualiza en los navegadores que admiten WebSocket, después de que se intercambia 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 mediante WebSocket o Socket.IO y el servidor envía tres mensajes en intervalos de 1 s, que el cliente agrega al DOM.

Lado del servidor

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

Servidor WebSocket

Ejemplo del 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 del 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

Lado del cliente

Compare 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 JavaScript vainilla:

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 del cliente Socket.IO usando JavaScript vainilla:

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 de red

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

Resultados de WebSocket

2 solicitudes, 1.50 KB, 0.05 s

De esas 2 solicitudes:

  1. Página HTML en sí
  2. actualización de conexión a WebSocket

(La solicitud de actualización de la conexión está visible en las herramientas del desarrollador con una respuesta de 101 protocolos de conmutación).

Resultados de Socket.IO

6 solicitudes, 181.56 KB, 0.25 s

De esas 6 solicitudes:

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

Capturas de pantalla

Resultados de WebSocket que obtuve en localhost:

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

Resultados de Socket.IO que obtuve en localhost:

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

Pruébate

Inicio rápido:

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

Abra http: // localhost: 3001 / en su navegador, abra las herramientas de desarrollador con Shift + Ctrl + I, abra la pestaña Red y vuelva a cargar la página con Ctrl + R para ver el tráfico de red para la versión WebSocket.

Abra http: // localhost: 3002 / en su navegador, abra las herramientas de desarrollador con Shift + Ctrl + I, abra la pestaña Red y vuelva a cargar 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 del navegador

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

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

ingrese la descripción de la imagen aquí

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

rsp
fuente
23
Entonces, ¿básicamente lo que estás diciendo es que websocket es mejor que socket.io?
Jack Moscovi
42
@JackMoscovi No diría que WebSocket es necesariamente mejor. Todo depende de los requisitos. Las ventajas de WebSocket son que es un estándar web (primero bajo W3C y whatwg, ahora bajo IETF, con un RFC publicado hace 5 años), es muy liviano porque es compatible de forma nativa con los navegadores, pero el soporte del navegador mientras es bueno es no universal Socket.IO admite más navegadores y tiene más funcionalidad, pero también viene con algunos gastos generales. A veces uno es mejor, a veces el otro. Es como elegir entre querySelectorAll y jQuery: la respuesta no siempre es la misma
rsp
20
Gran respuesta aquí !! Me parece que socket.io ya no es necesario en muchos casos ... ¡Vea este gran artículo también! medium.com/@ivanderbyl/…
Alvaro
44
@rsp ¿No creo que estos ejemplos sean funcionalmente equivalentes? Socket-io maneja cosas como la reconexión automática cuando se interrumpe (lo que sucede en los dispositivos móviles) y creo que existen problemas de seguridad en torno a lo que se manejan por usted. Sus ejemplos simples de WS, aunque funcionalmente equivalentes, no tienen estas propiedades.
mindplay.dk
28
Muy buena comparación. Sin embargo, vale la pena señalar que Socket.io agrega espaciado de nombre de sala, toneladas de detalles de conexión, muchos detalles de registro, y hay muchas bibliotecas de integración para Socket.IO con Angular, Vue, React y otros. Lo más importante es que puede deshabilitar el sondeo largo de Ajax y conectarse directamente a través de WebSocket al igual que una conexión WebSocket sin formato. De esta manera, obtienes todo excepto la biblioteca de 180 kb como iguales. Usar WebSocket directamente es doloroso a menos que solo necesite lo mínimo. Las salas de espera y el acceso a la IP de la comunidad son desalentadores para las empresas.
Nick Steele
30

Voy a proporcionar un argumento en contra del uso de socket.io.

Creo que usar socket.io únicamente porque tiene fallos 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. Puede consultar estas listas para ver ejemplos ... https://github.com/socketio/socket.io/issues?q=install+error

Si va a desarrollar una aplicación de Android o algo que necesita funcionar con su aplicación existente, probablemente estaría bien trabajar con WS de inmediato, socket.io podría darle algunos problemas allí ...

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

Victorio Berra
fuente
¿Qué sugieres que usemos para interactuar con mysql -> express.js / fastify.js o node.js directamente ... para construir aplicaciones de chat de Android e
iOS
25

Usar Socket.IO es básicamente como usar jQuery: desea admitir navegadores antiguos, necesita escribir menos código y la biblioteca proporcionará fallos. Socket.io usa la tecnología websockets si está disponible, y si no, verifica el mejor tipo de comunicación disponible y lo usa.

Dev Agrawal
fuente
3

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

Como se dijo en este tema, hay muchas bibliotecas de integración para Angular, React, etc. y tipos de definición para TypeScript y otros lenguajes de programación.

El otro punto que agregaría a las diferencias entre Socket.io y WebSockets es que el agrupamiento con Socket.io no es un gran problema. Socket.io ofrece adaptadores que se pueden usar para vincularlo con Redis para mejorar la escalabilidad. Tiene ioredis y socket.io-redis, por ejemplo.

Sí, lo sé, SocketCluster existe, pero eso está fuera de tema.

Maxime Lafarie
fuente
2

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

Nitina
fuente
0

https://socket.io/docs/#What-Socket-IO-is-not (con mi énfasis )

Lo que Socket.IO no es

Socket.IO NO es una implementación de WebSocket. Aunque Socket.IO de hecho usa WebSocket como transporte cuando es posible, agrega algunos metadatos a cada paquete: el tipo de paquete, el espacio de nombres y la identificación del paquete cuando se necesita un acuse de recibo del mensaje. Es por eso que un cliente WebSocket no podrá conectarse con éxito a un servidor Socket.IO , y un cliente Socket.IO tampoco podrá conectarse a un servidor WebSocket . Consulte la especificación del protocolo aquí .

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