Saltar al contenido principal

Socket.IO

Created by: Charlie Ovalle, 23 Mayo 2023

Socket.IO es una biblioteca que permite la comunicación de baja latencia, bidireccional y basada en eventos entre un cliente y un servidor.

bidirectional-communication2.png

Se basa en el protocolo WebSocket y ofrece garantías adicionales, como la posibilidad de recurrir a HTTP long-polling o la reconexión automática.

WebSocket es un protocolo de comunicación que proporciona un canal full-duplex y de baja latencia entre el servidor y el navegador. Aquí encontrará más información.

Existen varias implementaciones de servidores Socket.IO :

  • JavaScript (Node.js) (Web)
  • Python (

E implementaciones cliente en la mayoría de los principales idiomas:

  • Javascript (Web)
  • C++
  • C#
  • Python
  • Kotlin (Android)

Cómo funciona

El canal bidireccional entre el servidor Socket.IO (Node.js) y el cliente Socket.IO (navegador, Node.js, u otro lenguaje de programación) se establece con una conexión WebSocket siempre que sea posible, y utilizará HTTP long-polling como fallback.

El código base de Socket.IO está dividido en dos capas distintas:

  • la fontanería de bajo nivel: lo que llamamos Engine.IO, el motor dentro de Socket.IO
  • la API de alto nivel: Socket.IO

Engine.IO

Engine.IO se encarga de establecer la conexión de bajo nivel entre el servidor y el cliente. Se encarga de:

  • los distintos transportes y el mecanismo de actualización
  • la detección de desconexión

El protocolo Engine.IO permite la comunicación full-duplex y de baja sobrecarga entre un cliente y un servidor.

Se basa en el protocolo WebSocket y utiliza HTTP long-polling como alternativa si no se puede establecer la conexión WebSocket.

io.protocol

El número de revisión del protocolo (actualmente: 5).

El protocolo define el formato de los paquetes intercambiados entre el cliente y el servidor. Tanto el cliente como el servidor deben utilizar la misma revisión para entenderse.

Comunicación cliente-servidor Socket.io

Socket.io está basado en eventos, lo que significa que el cliente y el servidor se comunican a través de eventos. Tanto el cliente como el servidor pueden emitir y escuchar eventos y cada evento contiene un cuerpo que en la mayoría de los casos es un objeto JSON.

io.on("connection", (socket) => {
const tweet = {source: 'Peter', text: "Hello, world!"};
socket.emit('tweer', tweet)
})

socket.on("tweet", (tweet) => {
console.log("tweet from", tweet.source);
console.log("content:", tweet.text);
});

Cliente

Client API | Socket.IO

Manager/Socket

Constructor:

  • url [<string>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type)
  • options [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
  • Returns [<Manager>](https://socket.io/docs/v4/client-api/#manager)

Crea un nuevo Manager para la URL dada, e intenta reutilizar un Manager existente para llamadas posteriores, a menos que la opción multiplex se pase con false. Pasar esta opción es equivalente a pasar "forzar nueva conexión": true o forceNew: true.

Se devuelve una nueva instancia de Socket para “namespace” espeficado por la ruta en la URL, por defecto /. Por ejemplo, si la URL es http://localhost/users, se establecerá una conexión de transporte a http://localhost y una conexión Socket.IO a /users.

También se pueden proporcionar parámetros de query, ya sea con la opción query o directamente en la url (ejemplo: http://localhost/users?token=abc)..)

Para entender lo que sucede bajo el capó, el siguiente ejemplo:

import { io } from "socket.io-client";

const socket = io("ws://example.com/my-namespace", {
reconnectionDelayMax: 10000,
auth: {
token: "123"
},
query: {
"my-key": "my-value"
}
});

es la versión corta de:

import { Manager } from "socket.io-client";

const manager = new Manager("ws://example.com", {
reconnectionDelayMax: 10000,
query: {
"my-key": "my-value"
}
});

const socket = manager.socket("/my-namespace", {
auth: {
token: "123"
}
});

client-class-diagram-manager.png

El Manager gestiona la instancia cliente de Engine.IO, que es el motor de bajo nivel que establece la conexión con el servidor (utilizando transportes como WebSocket o HTTP long-polling).

El Manager maneja la lógica de reconexión.

Un único Manager puede ser utilizado por varios Sockets. Puede encontrar más información sobre esta función de multiplexación aquí.

Ten en cuenta que, en la mayoría de los casos, no utilizarás el Manager directamente, sino la instancia del Socket.

Eventos:

Client API | Socket.IO


Server

Constructor:

server-class-diagram-server.png

⚙ new Server(httpServer[, options])

  • httpServer [<http.Server>](https://nodejs.org/api/http.html#class-httpserver) | [<https.Server>](https://nodejs.org/api/https.html#class-httpsserver)
  • options [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)
import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, {
// options
});

io.on("connection", (socket) => {
// ...
});

httpServer.listen(3000);

Eventos:

Server API | Socket.IO