Diferencia entre Web Sockets y Socket.IO



¡Buen dia amigos!

Web sockets y Socket.IO son probablemente los dos medios más comunes de comunicación en tiempo real (en adelante, comunicación en vivo). ¿Pero cómo se diferencian?

Al crear una aplicación para la comunicación en vivo, llega un momento en que debe elegir una herramienta para intercambiar datos entre el cliente y el servidor. Web sockets y Socket.IO son los medios más populares de comunicación en vivo en la web moderna. ¿Cuál elegir? ¿Cuál es la diferencia entre estas tecnologías? Vamos a averiguar.

Tomas web


Hablando de sockets web, nos referimos al protocolo de comunicación web, que representa un canal de comunicación full-duplex a través de una simple conexión TCP. En pocas palabras, esta tecnología le permite establecer comunicación entre el cliente y el servidor con un costo mínimo, lo que le permite crear aplicaciones que utilizan todas las ventajas de la comunicación en vivo.

Por ejemplo, imagina que estás creando un chat: necesitas recibir y enviar datos lo más rápido posible, ¿verdad? ¡Los sockets web funcionan bien con esto! Puede abrir una conexión TCP y mantenerla abierta durante el tiempo que sea necesario.

Los sockets web aparecieron en 2010 en Google Chrome 4, el primer RFC ( 6455 ) se publicó en 2011.

Los sockets web se utilizan en los siguientes casos:

  • Chats
  • Juegos multijugador
  • Edición colaborativa
  • Alimentaciones sociales (noticias)
  • Aplicaciones basadas en ubicación

etc.

Socket.io


Socket.IO es una biblioteca de JavaScript basada (escrita en la parte superior) en sockets web ... y otras tecnologías. Utiliza sockets web cuando están disponibles, o tecnologías como Flash Socket, AJAX Long Polling, AJAX Multipart Stream, cuando los sockets web no están disponibles. Una analogía fácil es la comparación de Fetch API y Axios.

Diferencia entre Web Sockets y Socket.IO


Las principales ventajas de Socket.IO son las siguientes:

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

Puede parecer que Socket.IO es la mejor herramienta para la comunicación en vivo. Sin embargo, hay varias situaciones en las que es mejor usar sockets web.

En primer lugar, los sockets web son compatibles con todos los navegadores modernos. Por lo tanto, rara vez necesita el soporte de otras tecnologías proporcionadas por Socket.IO.

Si hablamos de tráfico de red, los sockets web solo envían dos solicitudes:

  • OBTENER para obtener la página HTML
  • ACTUALIZACIÓN para conectarse a tomas web

Esto le permite conectarse al servidor. ¿Qué pasa con Socket.IO?

  • OBTENER para obtener la página HTML
  • Biblioteca del cliente Socket.IO ( 207kb )
  • Tres largas solicitudes de sondeo de Ajax
  • ACTUALIZACIÓN para conectarse a tomas web

En el mundo de JS, 207kb es mucho. ¡Qué uso irracional del tráfico de red!

En npm hay un paquete "websocket-vs-socket.io" que le permite comparar el tráfico de red de estas tecnologías:

Tráfico de red de socket web:




Tráfico de red Socket.IO:




¡La diferencia es obvia!

Escribir un código


Servidor web simple


En nuestro programa en Node.js, crearemos un servidor que se ejecute en el puerto 3001. Cada vez que el cliente se conecte, le asignaremos un ID único. Al enviar un mensaje al cliente, le notificaremos el éxito: [<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}`)
  })
})

¡Multa! Pero, ¿qué pasa si queremos enviar un mensaje a cada cliente conectado? Los sockets web no admiten el envío de correos de forma predeterminada. Esto se puede implementar de la siguiente manera:

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

¡Simple y fácilmente! Como puede ver, WebSocket.Server mantiene registros de cada cliente conectado, para que podamos iterar y enviar un mensaje a todos. Puede probar el código en una computadora (MacOS) o en un navegador (Chrome) .

Servidor simple en Socket.IO


No fue dificil. ¿Puede Socket.IO hacerlo aún más fácil? ¿Cómo escribimos el mismo servidor en 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}`)
  })
})

¡El código es casi medio corto! Como puede ver, el método de transmisión no envía una notificación al remitente, por lo que nos vemos obligados a hacerlo manualmente.

Hay un problema: el código no se puede probar en un cliente de socket web normal. Esto se debe al hecho de que, como se señaló anteriormente, Socket.IO no utiliza sockets web puros, sino muchas tecnologías para admitir a todos los clientes posibles. Entonces, ¿cómo probamos su rendimiento?

// 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>

Debes usar un cliente especial. En el ejemplo anterior, lo cargamos desde el CDN. Este cliente nos permite realizar pruebas rápidas (sucias) en el navegador.

Como puede ver, nuestros ejemplos no son muy diferentes. Sin embargo, si hablamos de compatibilidad, debe recordarse que Socket.IO funciona con su propia biblioteca y no puede usarse para fines no relacionados con el desarrollo web. Al mismo tiempo, los sockets web se pueden usar para resolver una amplia gama de tareas, como la comunicación P2P, el intercambio de datos en tiempo real entre servidores, etc.

En una nota


Escalado horizontal. Supongamos que su chat ha ganado popularidad y necesita agregar otro servidor y equilibrador de carga para procesar las solicitudes. Bueno, si abre la conexión al "servidor 1", el equilibrador lo cambia al "servidor 2", obtendrá el error: "Error durante el protocolo de enlace WebSocket: código de respuesta inesperado: 400". Socket.IO resuelve este problema mediante el uso de cookies (o enrutando conexiones basadas en direcciones de origen), y los sockets web no tienen dicho mecanismo.
Actuación. Como se señaló anteriormente, Socket.IO proporciona varias capas abstractas sobre la capa de transporte de los sockets web. Además, aquí se usa el empaquetado de datos en formato JSON, por lo que no hay posibilidad de enviar datos binarios al servidor (y viceversa). Si necesita dicha funcionalidad, debe "conjurar" el código de la biblioteca para garantizar el comportamiento deseado. Con los sockets web, no surgen tales problemas.

Entonces, ¿qué elegir?


Tú decides.

Socket.IO hace la vida más fácil, no necesita preocuparse por problemas relacionados con el equilibrio de carga, la desconexión o el envío de mensajes ... pero ¿necesita esa funcionalidad? La biblioteca del cliente Socket.IO pesa más que los paquetes React, Redux y React-Redux combinados. ¿Estás seguro de que no puedes limitarte a los sockets web?

Otra cosa importante a tener en cuenta es que cuando se usa Socket.IO en el lado del servidor, la mayor parte del código se escribirá en las abstracciones proporcionadas por esta biblioteca. Si necesita reescribir los microservicios Node.js en Go, Elixir, Java u otro lenguaje de programación, deberá reescribir casi toda la lógica. Por ejemplo, para enviar mensajes a Socket.IO, se utiliza el método de "difusión" (que se implementa manualmente en los sockets web), por lo que al refactorizar tendrá que comprender cómo funciona este método. En este caso, se deben preferir los sockets web, ya que son más fáciles de adaptar.

Gracias por su atención.

All Articles