Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste tutorial, constróis um fluxo de chat simples em tempo real usando um hub de chat Web PubSub.
Tu:
- Configure um servidor backend para emitir URLs de acesso ao cliente
- Ligue clientes a um centro de chat Web PubSub
- Criar uma sala
- Enviar e receber mensagens
- Gerir a pertença a salas
No final, terá uma experiência de chat funcional suportada pelo Azure Web PubSub.
Pré-requisitos
- Uma assinatura do Azure
- Node.js 18 ou posterior
Crie um recurso Web PubSub com um centro de chat
Crie um recurso Azure Web PubSub e configure um hub de chat chamado demo-chat.
Instalar dependências
Dependências de servidores
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 ao cliente
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 }
);
Porque é que este passo existe
Embora o serviço Web PubSub suporte ligações anónimas, o padrão de produção mais comum utiliza um modelo de acesso emitido pelo servidor.
O seu servidor gera uma URL de acesso ao cliente com limite de tempo que codifica a identidade do utilizador e as permissões. Esta abordagem:
- Mantém as credenciais seguras
- Permite que a sua aplicação controle a autenticação e a autorização
- Alinha-se com as expectativas de segurança empresarial
Passo 2: Adicionar um endpoint de negociação
O ponto final de negociação devolve um URL de acesso para o cliente que os clientes de chat usam para se ligarem.
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,
});
});
Porque é que este passo existe
Os clientes de chat têm de se ligar como um utilizador específico.
O endpoint de negociação é onde a sua aplicação:
- Mapeia a identidade ao nível da aplicação para um utilizador de chat
- Gera um URL de acesso temporário com âmbito limitado
- Decide quem pode ligar-se
Em produção, este endpoint 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}`);
});
O seu backend está agora pronto para aceitar ligações de clientes.
Passo 4: Liga os clientes ao chat hub
No cliente, busca URLs de acesso do servidor e inicia sessão 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}`);
Porque é que este passo existe
O hub de chat Web PubSub baseia-se no modelo de ligação Web PubSub. Este passo de autenticação:
- Estabelece uma ligação em tempo real
- Associa a ligação a uma identidade de utilizador
- Permite funcionalidades específicas do chat, como salas e histórico de mensagens
Passo 5: Ouça os eventos de chat
Registe os 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, pode ouvir room-left, member-joined, member-left, started e stopped. Use off com os mesmos argumentos para remover um escutador.
Porque é que este passo existe
O chat é inerentemente orientado por eventos. Estes ouvintes permitem que a sua candidatura:
- Reagir às mensagens recebidas
- Atualize a interface quando os utilizadores entram nas salas
- Mantenha-se sincronizado em vários dispositivos ou separadores 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.
Porque é que este passo existe
As salas oferecem estrutura para conversas:
- Eles definem quem recebe as mensagens.
- Mantêm o histórico das mensagens.
- Permitem que o chat escale para além das mensagens individuais.
Passo 7: Obter o histórico de mensagens
Obter mensagens anteriores de uma sala.
listRoomMessages devolve um iterador assíncrono paginado, para que possas iterar diretamente sobre cada mensagem:
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 e depois mais 50 ao deslocar para cima"):
const pages = alice.listRoomMessages(room.roomId).byPage({ maxPageSize: 50 });
const firstPage = await pages.next();
const messages = firstPage.value ?? [];
Porque é que este passo existe
Clientes recém-ligados muitas vezes precisam de contexto.
O histórico de mensagens permite que a sua aplicação:
- Apresentar mensagens existentes
- Retomar a conversa após reconectar
- Suporte para utilização em vários dispositivos
Passo 8: Gerir os membros da sala
Adicionar um utilizador a uma sala:
await alice.addUserToRoom(room.roomId, 'bob');
Remover um utilizador de uma sala:
await alice.removeUserFromRoom(room.roomId, 'bob');
As alterações à adesão entram em vigor imediatamente.
Passo 9: Limpar
Quando o cliente já não precisa de receber mensagens:
await alice.stop();
await charlie.stop();
O que construíste
Neste guia de início rápido, você irá:
- URLs de acesso seguro ao cliente emitidos a partir de um servidor
- Clientes ligados a um centro de chat
- Criei e juntei-me a salas de chat
- Mensagens enviadas e recebidas em tempo real
- Histórico de mensagens carregadas
- Adesão a uma sala gerida
Tudo isto sem gerir servidores WebSocket, lógica de fan-out ou persistência de mensagens.