Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial, construyes un flujo de chat sencillo en tiempo real usando un hub de chat Web PubSub.
Tú:
- Configura un servidor backend para emitir URLs de acceso a los clientes
- Conecta clientes con un centro de chat Web PubSub
- Creación de una sala
- Enviar y recibir mensajes
- Gestionar la membresía de la sala
Al final, tienes una experiencia de chat de trabajo respaldada por Azure Web PubSub.
Prerequisites
- Una suscripción de Azure
- Node.js 18 o posterior
Crea un recurso Web PubSub con un centro de chat
Crea un recurso de Azure Web PubSub y configura un chat hub llamado demo-chat.
Instalación de dependencias
Dependencias de servidor
npm install express @azure/web-pubsub @azure/web-pubsub-express
Dependencias del cliente
npm install @azure/web-pubsub-chat-client
Paso 1: Crear el servidor backend
El servidor backend es responsable de:
- Autenticación de usuarios
- Emisión de URLs de acceso al cliente
Código del servidor
import express from 'express';
import { WebPubSubServiceClient } from '@azure/web-pubsub';
import { WebPubSubEventHandler } from '@azure/web-pubsub-express';
const hubName = 'demo-chat';
const port = process.env.PORT || 3000;
const connectionString = process.env.WEB_PUBSUB_CONNECTION_STRING;
if (!connectionString) {
throw new Error('WEB_PUBSUB_CONNECTION_STRING is not set');
}
const app = express();
const serviceClient = new WebPubSubServiceClient(
connectionString,
hubName,
{ allowInsecureConnection: true }
);
Por qué existe este paso
Aunque el servicio Web PubSub soporta conexiones anónimas, el patrón de producción más común utiliza un modelo de acceso emitido por el servidor.
Tu servidor genera una URL de acceso al cliente con límite de tiempo que codifica la identidad del usuario y los permisos. Este enfoque:
- Mantiene las credenciales seguras
- Permite que tu aplicación controle la autenticación y la autorización
- Está en línea con las expectativas de seguridad empresarial
Paso 2: Añadir un punto final de negociación
El punto final de negociación devuelve una URL de acceso al cliente que los clientes de chat usan para conectarse.
app.get('/negotiate', async (req, res) => {
console.log(`received negotiate request: ${JSON.stringify(req.query)}`);
const userId = req.query.userId;
if (!userId) {
return res.status(400).send('Missing userId');
}
const token = await serviceClient.getClientAccessToken({
userId,
});
res.json({
url: token.url,
});
});
Por qué existe este paso
Los clientes de chat deben conectarse como un usuario específico.
El punto de conexión de negociación es donde tu aplicación:
- Asigna una identidad a nivel de aplicación a un usuario de chat
- Emite una URL de acceso temporal de alcance limitado
- Decide quién puede conectar
En producción, este punto final suele ser:
- Verifica la autenticación (cookies, encabezados, tokens)
- Hace cumplir las normas de autorización
Paso 3: Iniciar el servidor
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Tu backend ya está listo para aceptar conexiones de clientes.
Paso 4: Conecta a los clientes con el chat hub
En el cliente, busca las URLs de acceso del servidor e inicia sesión en el demo-chat hub.
import { ChatClient } from '@azure/web-pubsub-chat-client';
// Fetch a fresh client access URL from the negotiate endpoint.
const getClientAccessUrl = (userId) =>
fetch(`/negotiate?userId=${userId}`)
.then(r => r.json())
.then(d => d.url);
// Option 1: start with a one-time client access URL.
const alice = await ChatClient.start(await getClientAccessUrl('alice'));
console.log(`Started as: ${alice.userId}`);
// Option 2: start with a credential so the client can refresh the URL itself.
const charlie = await ChatClient.start({
getClientAccessUrl: () => getClientAccessUrl('charlie'),
});
console.log(`Started as: ${charlie.userId}`);
Por qué existe este paso
El hub de chat de Web PubSub se basa en el modelo de conexión Web PubSub. Este paso de autenticación:
- Establece una conexión en tiempo real
- Asocia la conexión con la identidad de un usuario
- Permite funciones específicas del chat como salas e historial de mensajes
Paso 5: Escucha los eventos de chat
Regístrate a los oyentes para recibir actualizaciones en tiempo real.
alice.on('message', (event) => {
const msg = event.message;
console.log(`Alice received: ${msg.createdBy}: ${msg.content.text}`);
});
alice.on('room-joined', (event) => {
console.log(`Alice joined room: ${event.room.title}`);
});
charlie.on('message', (event) => {
const msg = event.message;
console.log(`Charlie received: ${msg.createdBy}: ${msg.content.text}`);
});
charlie.on('room-joined', (event) => {
console.log(`Charlie joined room: ${event.room.title}`);
});
El cliente de chat es un emisor de eventos. Además de message y room-joined, puedes detectar room-left, member-joined, member-left, started y stopped. Úsalo off con los mismos argumentos para eliminar a un oyente.
Por qué existe este paso
El chat es inherentemente impulsado por eventos. Estos oyentes permiten a tu aplicación:
- Reaccionar a los mensajes entrantes
- Actualiza la interfaz cuando los usuarios se unan a las salas
- Mantente sincronizado en varios dispositivos o pestañas del navegador
Paso 6: Crea una habitación y envía mensajes
Crea una sala y añade miembros iniciales:
const room = await alice.createRoom('My Room', ['charlie']);
Envía un mensaje a la sala:
await alice.sendToRoom(room.roomId, 'Hello!');
Los mensajes se entregan en tiempo real a todos los miembros de la sala.
Por qué existe este paso
Las salas ofrecen estructura para el chat:
- Definen quién recibe los mensajes.
- Mantienen el historial de mensajes.
- Permiten que el chat escale más allá de la mensajería uno a uno.
Paso 7: Obtener el historial de mensajes
Recuperar mensajes anteriores de una sala.
listRoomMessages devuelve un iterador asíncrono paginado, para que puedas iterar directamente sobre cada mensaje:
for await (const msg of alice.listRoomMessages(room.roomId)) {
console.log(`${msg.createdBy}: ${msg.content.text}`);
}
O cargar el historial de una página cada vez (por ejemplo, "cargar 50 y luego 50 más al desplazarse hacia arriba"):
const pages = alice.listRoomMessages(room.roomId).byPage({ maxPageSize: 50 });
const firstPage = await pages.next();
const messages = firstPage.value ?? [];
Por qué existe este paso
Los clientes recién conectados suelen necesitar contexto.
El historial de mensajes permite que tu aplicación:
- Mostrar mensajes existentes
- Reanudar el chat tras reconectarnos
- Soporte para uso multidispositivo
Paso 8: Gestionar a los miembros de la sala
Añadir un usuario a una sala:
await alice.addUserToRoom(room.roomId, 'bob');
Sacar a un usuario de una sala:
await alice.removeUserFromRoom(room.roomId, 'bob');
Los cambios de membresía entran en vigor de inmediato.
Paso 9: Limpiar
Cuando el cliente ya no necesita recibir mensajes:
await alice.stop();
await charlie.stop();
Lo que ha creado
En esta guía de inicio rápido, aprenderá a:
- Emitieron URLs de acceso seguro al cliente desde un servidor
- Conecté clientes a un centro de chat
- Creé y me uní a salas de chat
- Mensajes enviados y recibidos en tiempo real
- Historial de mensajes cargados
- Pertenencia administrada a salas
Todo ello sin gestionar servidores WebSocket, lógica de dispersión o persistencia de mensajes.