Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym tutorialu budujesz prosty przepływ czatu w czasie rzeczywistym, korzystając z chatu Web PubSub.
Ty:
- Ustaw serwer backendowy do wydawania adresów dostępu klienta
- Połącz klientów z chatem Web PubSub
- Utwórz pokój
- Wysyłanie i odbieranie komunikatów
- Zarządzaj członkostwem w pokoju
Na koniec masz działające doświadczenie czatu wspieranego przez Azure Web PubSub.
Wymagania wstępne
- Subskrypcja platformy Azure
- Node.js 18 lub nowsza wersja
Utwórz zasób Web PubSub z centrum czatu
Stwórz zasób Azure Web PubSub i skonfiguruj hub czatu o nazwie demo-chat.
Instalowanie zależności
Zależności serwera
npm install express @azure/web-pubsub @azure/web-pubsub-express
Zależności klientów
npm install @azure/web-pubsub-chat-client
Krok 1: Stwórz serwer backend
Serwer backend odpowiada za:
- Uwierzytelnianie użytkowników
- Wysyłanie adresów URL dostępu klienta
Kod serwera
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 }
);
Dlaczego ten krok istnieje
Chociaż usługa Web PubSub obsługuje anonimowe połączenia, najczęściej stosowany jest model dostępu wydawany przez serwer.
Twój serwer generuje ograniczony czasowo adres URL dostępu klienta , który koduje tożsamość użytkownika i uprawnienia. Takie podejście:
- Zabezpiecza dane uwierzytelniające
- Pozwala Twojej aplikacji kontrolować uwierzytelnianie i autoryzację
- Zgodna z oczekiwaniami dotyczącymi bezpieczeństwa przedsiębiorstwa
Krok 2: Dodaj punkt końcowy negocjacji
Punkt końcowy negocjacji zwraca adres URL dostępu klienta, którego klienci czatu używają do połączenia.
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,
});
});
Dlaczego ten krok istnieje
Klienci czatu muszą łączyć się jako konkretny użytkownik.
Punkt końcowy negocjacji to miejsce, gdzie Twoja aplikacja:
- Przypisuje tożsamość na poziomie aplikacji do użytkownika czatu
- Wydaje ograniczony, tymczasowy adres URL dostępu
- Decyduje, kto może nawiązać połączenie
W produkcji ten punkt końcowy zazwyczaj następuje:
- Weryfikuje uwierzytelnianie (ciasteczka, nagłówki, tokeny)
- Egzekwuje zasady autoryzacji
Krok 3: Uruchom serwer
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
Twój backend jest teraz gotowy do przyjmowania połączeń z klientami.
Krok 4: Połącz klientów z chatem hub
Na kliencie pobieraj adresy URL dostępu z serwera i loguj się do huba demo-chat .
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}`);
Dlaczego ten krok istnieje
Hub czatu Web PubSub opiera się na modelu połączenia Web PubSub. Ten krok uwierzytelniania:
- Ustanawia połączenie w czasie rzeczywistym
- Kojarzy połączenie z tożsamością użytkownika
- Umożliwia funkcje specyficzne dla czatu, takie jak pokoje i historia wiadomości
Krok 5: Słuchaj wydarzeń czatowych
Rejestruj słuchaczy, aby otrzymywać aktualizacje w czasie rzeczywistym.
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}`);
});
Klient czatu to emiter zdarzeń. Oprócz message i room-joined, można słuchać room-left, member-joined, member-left, started, oraz stopped. Używam off z tymi samymi argumentami, aby usunąć słuchacza.
Dlaczego ten krok istnieje
Czat jest z natury napędzany wydarzeniami. Ci słuchacze pozwalają Twojej aplikacji na:
- Reaguj na nadchodzące wiadomości
- Aktualizuj interfejs użytkownika, gdy użytkownicy dołączają do pokoi
- Zostań zsynchronizowany na wielu urządzeniach lub zakładkach przeglądarki
Krok 6: Stwórz pokój i wyślij wiadomości
Stwórz pokój i dodaj początkowych członków:
const room = await alice.createRoom('My Room', ['charlie']);
Wyślij wiadomość do pokoju:
await alice.sendToRoom(room.roomId, 'Hello!');
Wiadomości są dostarczane w czasie rzeczywistym do wszystkich członków sali.
Dlaczego ten krok istnieje
Pokoje zapewniają strukturę do czatu:
- To oni definiują, kto otrzymuje wiadomości.
- Utrzymują historię wiadomości.
- Pozwalają na skalowanie czatu poza komunikację jeden do jednego.
Krok 7: Pobierz historię wiadomości
Pobierz wcześniejsze wiadomości z pokoju.
listRoomMessages zwraca stronicowany iterator asynchroniczny, dzięki czemu możesz bezpośrednio iterować po wszystkich wiadomościach:
for await (const msg of alice.listRoomMessages(room.roomId)) {
console.log(`${msg.createdBy}: ${msg.content.text}`);
}
Albo ładuj historię strona po stronie (na przykład „załaduj 50, potem kolejne 50 podczas przewijania w górę”):
const pages = alice.listRoomMessages(room.roomId).byPage({ maxPageSize: 50 });
const firstPage = await pages.next();
const messages = firstPage.value ?? [];
Dlaczego ten krok istnieje
Nowo połączeni klienci często potrzebują kontekstu.
Historia wiadomości pozwala Twojej aplikacji:
- Renderowanie istniejących komunikatów
- Wznowij czat po ponownym połączeniu
- Obsługa wielu urządzeń
Krok 8: Zarządzaj członkami sali
Dodaj użytkownika do pokoju:
await alice.addUserToRoom(room.roomId, 'bob');
Usuń użytkownika z pokoju:
await alice.removeUserFromRoom(room.roomId, 'bob');
Zmiany członkostwa wchodzą w życie natychmiast.
Krok 9: Posprzątaj
Gdy klient nie musi już otrzymywać wiadomości:
await alice.stop();
await charlie.stop();
Co utworzono
W ramach tego szybkiego przewodnika wykonasz następujące czynności:
- Wydano bezpieczne adresy URL dostępu klienta z serwera
- Klienci połączeni z centrum czatu
- Utworzone i dołączone pokoje czatu
- Wysyłane i odbierane wiadomości w czasie rzeczywistym
- Wczytana historia wiadomości
- Członkostwo w zarządzanych pokojach
Wszystko to bez zarządzania serwerami WebSocket, logiką rozprzestrzeniania się czy utrzymywania wiadomości.