Ir al contenido principal
Versión: 4.x

Namespaces

Un Namespace es un canal de comunicación que te permite dividir la lógica de tu aplicación sobre una única conexión compartida (también llamado "multiplexación").

Diagrama de NamespaceDiagrama de Namespace

Introducción

Cada namespace tiene sus propios:

io.of("/orders").on("connection", (socket) => {
socket.on("order:list", () => {});
socket.on("order:create", () => {});
});

io.of("/users").on("connection", (socket) => {
socket.on("user:list", () => {});
});
const orderNamespace = io.of("/orders");

orderNamespace.on("connection", (socket) => {
socket.join("room1");
orderNamespace.to("room1").emit("hello");
});

const userNamespace = io.of("/users");

userNamespace.on("connection", (socket) => {
socket.join("room1"); // distinta de la sala en el namespace "orders"
userNamespace.to("room1").emit("holà");
});
const orderNamespace = io.of("/orders");

orderNamespace.use((socket, next) => {
// asegurar que el socket tiene acceso al namespace "orders", y luego
next();
});

const userNamespace = io.of("/users");

userNamespace.use((socket, next) => {
// asegurar que el socket tiene acceso al namespace "users", y luego
next();
});

Posibles casos de uso:

  • quieres crear un namespace especial al que solo usuarios autorizados tienen acceso, así la lógica relacionada con esos usuarios está separada del resto de la aplicación
const adminNamespace = io.of("/admin");

adminNamespace.use((socket, next) => {
// asegurar que el usuario tiene suficientes derechos
next();
});

adminNamespace.on("connection", socket => {
socket.on("delete user", () => {
// ...
});
});
  • tu aplicación tiene múltiples tenants así que quieres crear dinámicamente un namespace por tenant
const workspaces = io.of(/^\/\w+$/);

workspaces.on("connection", socket => {
const workspace = socket.nsp;

workspace.emit("hello");
});

Namespace principal

Hasta ahora, has interactuado con el namespace principal, llamado /. La instancia io hereda todos sus métodos:

io.on("connection", (socket) => {});
io.use((socket, next) => { next() });
io.emit("hello");
// son en realidad equivalentes a
io.of("/").on("connection", (socket) => {});
io.of("/").use((socket, next) => { next() });
io.of("/").emit("hello");

Algunos tutoriales también pueden mencionar io.sockets, es simplemente un alias para io.of("/").

io.sockets === io.of("/")

Namespaces personalizados

Para configurar un namespace personalizado, puedes llamar a la función of en el lado del servidor:

const nsp = io.of("/my-namespace");

nsp.on("connection", socket => {
console.log("alguien se conectó");
});

nsp.emit("hi", "¡todos!");

Inicialización del cliente

Versión del mismo origen:

const socket = io(); // o io("/"), el namespace principal
const orderSocket = io("/orders"); // el namespace "orders"
const userSocket = io("/users"); // el namespace "users"

Versión cross-origin/Node.js:

const socket = io("https://example.com"); // o io("https://example.com/"), el namespace principal
const orderSocket = io("https://example.com/orders"); // el namespace "orders"
const userSocket = io("https://example.com/users"); // el namespace "users"

En el ejemplo anterior, solo se establecerá una conexión WebSocket, y los paquetes serán enrutados automáticamente al namespace correcto.

Por favor nota que la multiplexación será deshabilitada en los siguientes casos:

  • múltiples creaciones para el mismo namespace
const socket1 = io();
const socket2 = io(); // sin multiplexación, dos conexiones WebSocket distintas
  • diferentes dominios
const socket1 = io("https://first.example.com");
const socket2 = io("https://second.example.com"); // sin multiplexación, dos conexiones WebSocket distintas
const socket1 = io();
const socket2 = io("/admin", { forceNew: true }); // sin multiplexación, dos conexiones WebSocket distintas

Namespaces dinámicos

También es posible crear namespaces dinámicamente, ya sea con una expresión regular:

io.of(/^\/dynamic-\d+$/);

o con una función:

io.of((name, auth, next) => {
next(null, true); // o false, cuando la creación es denegada
});

Puedes tener acceso al nuevo namespace en el evento connection:

io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
const namespace = socket.nsp;
});

El valor de retorno del método of() es lo que llamamos el namespace padre, desde el cual puedes:

const parentNamespace = io.of(/^\/dynamic-\d+$/);

parentNamespace.use((socket, next) => { next() });

El middleware se registrará automáticamente en cada namespace hijo.

const parentNamespace = io.of(/^\/dynamic-\d+$/);

parentNamespace.emit("hello"); // se enviará a usuarios en /dynamic-1, /dynamic-2, ...
precaución

Los namespaces existentes tienen prioridad sobre los namespaces dinámicos. Por ejemplo:

// registrar namespace "dynamic-101"
io.of("/dynamic-101");

io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
// no se llamará para una conexión en el namespace "dynamic-101"
});

API completa

La API completa expuesta por la instancia Namespace se puede encontrar aquí.