Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste tutorial, você constrói um fluxo de chat simples em tempo real usando um hub de chat Web PubSub.
Você:
- Configure um servidor backend para emitir URLs de acesso ao cliente
- Conecte clientes a um hub de chat Web PubSub
- Criar uma sala
- Enviar e receber mensagens
- Gerencie a associação de quartos
Ao final, você tem uma experiência de chat de trabalho respaldada pelo Azure Web PubSub.
Pré-requisitos
- Uma assinatura de Azure
- Node.js 18 ou posterior
Crie um recurso Web PubSub com um hub de chat
Crie um recurso Azure Web PubSub e configure um hub de chat chamado demo-chat.
Instalar dependências
Dependências de servidor
npm install express @azure/web-pubsub @azure/web-pubsub-express
Dependências do cliente
npm install @azure/web-pubsub-chat-client
Passo 1: Criar o servidor backend
O servidor backend é responsável por:
- Autenticando usuários
- Emissão de URLs de acesso dos clientes
Código do 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 que esse passo existe
Embora o serviço Web PubSub suporte conexões anônimas, o padrão de produção mais comum utiliza um modelo de acesso fornecido pelo servidor.
Seu servidor gera uma URL de acesso ao cliente com tempo limitado que codifica a identidade do usuário e as permissões. Essa abordagem:
- Mantém as credenciais seguras
- Permite que seu app controle autenticação e autorização
- Está alinhado com as expectativas de segurança corporativa
Passo 2: Adicionar um endpoint de negociação
O endpoint de negociação retorna uma URL de acesso que os clientes de chat usam para se conectar.
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 que esse passo existe
Os clientes de chat devem se conectar como um usuário específico.
O ponto de extremidade de negociação é o ponto em que seu aplicativo:
- Mapeia identidade em nível de aplicativo para um usuário de chat
- Gera uma URL temporária de acesso com escopo definido
- Decide quem pode se conectar
Em produção, este ponto de extremidade tipicamente:
- Verifica autenticação (cookies, cabeçalhos, tokens)
- Aplica regras de autorização
Passo 3: Iniciar o servidor
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Seu backend agora está pronto para aceitar conexões de clientes.
Passo 4: Conecte os clientes ao hub de chat
No cliente, busque URLs de acesso do servidor e faça login no 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 que esse passo existe
O hub de chat Web PubSub se baseia no modelo de conexão Web PubSub. Esta etapa de autenticação:
- Estabelece uma conexão em tempo real
- Associa a conexão a uma identidade de usuário
- Permite recursos específicos do chat, como salas e histórico de mensagens
Passo 5: Ouça os eventos de chat
Registre ouvintes para receber atualizações em tempo 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}`);
});
O cliente de chat é um emissor de eventos. Além de message e room-joined, você pode detectar room-left, member-joined, member-left, started e stopped. Use off com os mesmos argumentos para remover um ouvinte.
Por que esse passo existe
O chat é inerentemente movido por eventos. Esses detectores permitem que seu aplicativo faça:
- Reagir às mensagens recebidas
- Atualiza a interface do usuário quando os usuários entram nas salas
- Mantenha a sincronização entre vários dispositivos ou abas do navegador
Passo 6: Crie uma sala e envie mensagens
Crie uma sala e adicione membros iniciais:
const room = await alice.createRoom('My Room', ['charlie']);
Envie uma mensagem para a sala:
await alice.sendToRoom(room.roomId, 'Hello!');
As mensagens são entregues em tempo real a todos os membros da sala.
Por que esse passo existe
Salas oferecem estrutura para conversas:
- Eles definem quem recebe as mensagens.
- Eles mantêm o histórico de mensagens.
- Eles permitem que o chat escale além da mensagem um para um.
Passo 7: Obter histórico de mensagens
Recupere mensagens anteriores de uma sala.
listRoomMessages retorna um iterador assíncrono paginado, para que você possa iterar sobre cada mensagem diretamente:
for await (const msg of alice.listRoomMessages(room.roomId)) {
console.log(`${msg.createdBy}: ${msg.content.text}`);
}
Ou carregar o histórico uma página de cada vez (por exemplo, "carregar 50, depois mais 50 na rolagem para cima"):
const pages = alice.listRoomMessages(room.roomId).byPage({ maxPageSize: 50 });
const firstPage = await pages.next();
const messages = firstPage.value ?? [];
Por que esse passo existe
Clientes recém-conectados frequentemente precisam de contexto.
O histórico de mensagens permite que seu app:
- Exibir mensagens existentes
- Retomar o chat após a reconexão
- Suporte ao uso multidispositivo
Passo 8: Gerencie os membros da sala
Adicione um usuário a uma sala:
await alice.addUserToRoom(room.roomId, 'bob');
Remover um usuário de uma sala:
await alice.removeUserFromRoom(room.roomId, 'bob');
As mudanças de membros entram em vigor imediatamente.
Passo 9: Limpar
Quando o cliente não precisa mais receber mensagens:
await alice.stop();
await charlie.stop();
O que você criou
Neste guia de início rápido, você:
- URLs de acesso seguro ao cliente emitidas a partir de um servidor
- Conectei clientes a um hub de chat
- Criei e entrou em salas de bate-papo
- Mensagens enviadas e recebidas em tempo real
- Histórico de mensagens carregadas
- Associação a salas gerenciadas
Tudo isso sem gerenciar servidores WebSocket, lógica de espalhamento ou persistência de mensagens.