Kurz: Vytvoření chatovací aplikace pomocí služby Azure Web PubSub
V kurzu Publikování a přihlášení k odběru zpráv se naučíte základy publikování a přihlášení k odběru zpráv pomocí azure Web PubSub. V tomto kurzu se seznámíte se systémem událostí Azure Web PubSub a použijete ho k vytvoření kompletní webové aplikace s funkcemi komunikace v reálném čase.
V tomto kurzu se naučíte:
- Vytvoření instance služby Web PubSub
- Konfigurace nastavení obslužné rutiny události pro Azure Web PubSub
- Zpracování událostí na aplikačním serveru a vytvoření chatovací aplikace v reálném čase
Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet Azure před tím, než začnete.
Požadavky
Použijte prostředí Bash v Azure Cloud Shellu. Další informace najdete v tématu Rychlý start pro Bash v Azure Cloud Shellu.
Pokud dáváte přednost místnímu spouštění referenčních příkazů rozhraní příkazového řádku, nainstalujte Azure CLI. Pokud používáte Windows nebo macOS, zvažte spuštění Azure CLI v kontejneru Docker. Další informace najdete v tématu Jak spustit Azure CLI v kontejneru Dockeru.
Pokud používáte místní instalaci, přihlaste se k Azure CLI pomocí příkazu az login. Pokud chcete dokončit proces ověřování, postupujte podle kroků zobrazených na terminálu. Další možnosti přihlášení najdete v tématu Přihlášení pomocí Azure CLI.
Po zobrazení výzvy nainstalujte rozšíření Azure CLI při prvním použití. Další informace o rozšířeních najdete v tématu Využití rozšíření v Azure CLI.
Spuštěním příkazu az version zjistěte verzi a závislé knihovny, které jsou nainstalované. Pokud chcete upgradovat na nejnovější verzi, spusťte az upgrade.
- Tato instalace vyžaduje verzi 2.22.0 nebo vyšší rozhraní příkazového řádku Azure CLI. Pokud používáte Azure Cloud Shell, je už nainstalovaná nejnovější verze.
Vytvoření instance Azure Web PubSub
Vytvoření skupiny zdrojů
Skupina prostředků je logický kontejner, ve kterém se nasazují a spravují prostředky Azure. Pomocí příkazu az group create vytvořte skupinu prostředků s názvem myResourceGroup
v eastus
umístění.
az group create --name myResourceGroup --location EastUS
Vytvoření instance Web PubSub
Spuštěním příkazu az extension add nainstalujte nebo upgradujte rozšíření webpubsub na aktuální verzi.
az extension add --upgrade --name webpubsub
Pomocí příkazu az webpubsub az webpubsub vytvořte web pubSub ve skupině prostředků, kterou jste vytvořili. Následující příkaz vytvoří prostředek Free Web PubSub ve skupině prostředků myResourceGroup v eastUS:
Důležité
Každý prostředek Web PubSub musí mít jedinečný název. V následujících příkladech nahraďte <název_prostředku-unique-resource názvem> podsítě Web PubSub.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
Výstup tohoto příkazu zobrazuje vlastnosti nově vytvořeného prostředku. Poznamenejte si hodnoty dvou vlastností uvedených níže:
- Název prostředku: Název, který jste zadali výše uvedenému parametru
--name
. - hostName: V příkladu je
<your-unique-resource-name>.webpubsub.azure.com/
název hostitele .
V tuto chvíli je váš účet Azure jediným autorizovaným k provádění jakýchkoli operací s tímto novým prostředkem.
Získání připojovacího řetězce pro budoucí použití
Důležité
Nezpracované připojovací řetězec se v tomto článku zobrazují jenom pro demonstrační účely.
Připojovací řetězec obsahuje informace o autorizaci vyžadované pro vaši aplikaci pro přístup ke službě Azure Web PubSub. Přístupový klíč uvnitř připojovací řetězec je podobný kořenovému heslu pro vaši službu. V produkčních prostředích vždy chraňte přístupové klíče. Pomocí služby Azure Key Vault můžete bezpečně spravovat a obměňovat klíče a zabezpečit připojení WebPubSubServiceClient
.
Vyhněte se distribuci přístupových klíčů ostatním uživatelům, jejich pevnému kódování nebo jejich uložení kdekoli ve formátu prostého textu, který je přístupný ostatním uživatelům. Otočte klíče, pokud se domníváte, že mohly být ohroženy.
K získání připojovacího řetězce služby použijte příkaz azure CLI az webpubsub key. <your-unique-resource-name>
Zástupný symbol nahraďte názvem vaší instance Azure Web PubSub.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Zkopírujte připojovací řetězec pro pozdější použití.
Zkopírujte načtený ConnectionString a nastavte ho do proměnné WebPubSubConnectionString
prostředí, kterou si kurz později přečte. Nahraďte <connection-string>
ho řetězcem ConnectionString , který jste načítáli.
export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>
Nastavení projektu
Požadavky
Vytvoření aplikace
Ve službě Azure Web PubSub existují dvě role, server a klient. Tento koncept se podobá rolím serveru a klienta ve webové aplikaci. Server zodpovídá za správu klientů, naslouchání a odpovídá na zprávy klientů. Klient zodpovídá za odesílání a přijímání zpráv uživatele ze serveru a jejich vizualizaci pro koncového uživatele.
V tomto kurzu vytvoříme webovou aplikaci chatu v reálném čase. V reálné webové aplikaci také odpovědnost serveru zahrnuje ověřování klientů a obsluhu statických webových stránek pro uživatelské rozhraní aplikace.
K hostování webových stránek a zpracování příchozích požadavků používáme ASP.NET Core 8 .
Nejprve vytvoříme webovou aplikaci ASP.NET Core ve chatapp
složce.
Vytvořte novou webovou aplikaci.
mkdir chatapp cd chatapp dotnet new web
Přidejte
app.UseStaticFiles()
Program.cs pro podporu hostování statických webových stránek.var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseStaticFiles(); app.Run();
Vytvořte soubor HTML a uložte ho jako
wwwroot/index.html
, použijeme ho pro uživatelské rozhraní chatovací aplikace později.<html> <body> <h1>Azure Web PubSub Chat</h1> </body> </html>
Server můžete otestovat spuštěním dotnet run --urls http://localhost:8080
a přístupem http://localhost:8080/index.html
v prohlížeči.
Přidání koncového bodu negotiate
V kurzu Publikovat a přihlásit se k odběru zprávy, odběratel využívá připojovací řetězec přímo. V reálné aplikaci není bezpečné sdílet připojovací řetězec s žádným klientem, protože připojovací řetězec má vysoké oprávnění k provedení jakékoli operace se službou. Teď vezměme server, který využívá připojovací řetězec, a vystavení koncového negotiate
bodu pro klienta, aby získal úplnou adresu URL s přístupovým tokenem. Server tak může před koncový bod přidat ověřovací middleware negotiate
, aby se zabránilo neoprávněnému přístupu.
Nejprve nainstalujte závislosti.
dotnet add package Microsoft.Azure.WebPubSub.AspNetCore
Teď přidáme /negotiate
koncový bod pro volání klienta pro vygenerování tokenu.
using Azure.Core;
using Microsoft.Azure.WebPubSub.AspNetCore;
using Microsoft.Azure.WebPubSub.Common;
using Microsoft.Extensions.Primitives;
// Read connection string from environment
var connectionString = Environment.GetEnvironmentVariable("WebPubSubConnectionString");
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWebPubSub(o => o.ServiceEndpoint = new WebPubSubServiceEndpoint(connectionString))
.AddWebPubSubServiceClient<Sample_ChatApp>();
var app = builder.Build();
app.UseStaticFiles();
// return the Client Access URL with negotiate endpoint
app.MapGet("/negotiate", (WebPubSubServiceClient<Sample_ChatApp> service, HttpContext context) =>
{
var id = context.Request.Query["id"];
if (StringValues.IsNullOrEmpty(id))
{
context.Response.StatusCode = 400;
return null;
}
return new
{
url = service.GetClientAccessUri(userId: id).AbsoluteUri
};
});
app.Run();
sealed class Sample_ChatApp : WebPubSubHub
{
}
AddWebPubSubServiceClient<THub>()
se používá k vložení klienta WebPubSubServiceClient<THub>
služby, se kterým můžeme v kroku vyjednávání vygenerovat token připojení klienta a v metodách centra k vyvolání rozhraní REST API služby při aktivaci událostí centra. Tento kód generování tokenu je podobný kódu, který jsme použili v kurzu k publikování a odběru zpráv, s výjimkou toho, že při generování tokenu předáme jeden další argument (userId
). ID uživatele lze použít k identifikaci identity klienta, takže když obdržíte zprávu, ze které víte, odkud zpráva pochází.
Kód čte připojovací řetězec z proměnné WebPubSubConnectionString
prostředí, kterou jsme nastavili v předchozím kroku.
Znovu spusťte server pomocí dotnet run --urls http://localhost:8080
.
Toto rozhraní API můžete otestovat tak, že ho otevřete http://localhost:8080/negotiate?id=user1
a získáte úplnou adresu URL podsítě Azure Web PubSub s přístupovým tokenem.
Zpracování událostí
Pokud na straně klienta dojde k určitým aktivitám v podsítě Azure Web PubSub (například klient se připojuje, připojuje, odpojí nebo odesílá zprávy), služba odesílá oznámení na server, aby na tyto události reagovala.
Události se doručují na server ve formě Webhooku. Webhook obsluhuje a vystavuje aplikační server a je zaregistrovaný na straně služby Azure Web PubSub. Služba vyvolá webhooky vždy, když dojde k události.
Azure Web PubSub sleduje CloudEvents a popisuje data událostí.
Níže zpracováváme connected
systémové události při připojení klienta a zpracování message
uživatelských událostí, když klient odesílá zprávy pro sestavení chatovací aplikace.
Sada Web PubSub SDK pro AspNetCore Microsoft.Azure.WebPubSub.AspNetCore
, která jsme nainstalovali v předchozím kroku, může také pomoct analyzovat a zpracovávat požadavky CloudEvents.
Nejprve přidejte obslužné rutiny událostí před app.Run()
. Zadejte cestu koncového bodu pro události, řekněme /eventhandler
.
app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();
Teď do třídy Sample_ChatApp
, kterou jsme vytvořili v předchozím kroku, přidejte konstruktor pro práci s WebPubSubServiceClient<Sample_ChatApp>
tím, který používáme k vyvolání služby Web PubSub. A OnConnectedAsync()
reagovat, když connected
se událost aktivuje, OnMessageReceivedAsync()
aby se zpracovávaly zprávy z klienta.
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
Ve výše uvedeném kódu používáme klienta služby k vysílání zprávy s oznámením ve formátu JSON všem, s kým je připojen SendToAllAsync
.
Aktualizace webové stránky
Teď aktualizujeme index.html
, abychom přidali logiku pro připojení, odeslání zprávy a zobrazení přijatých zpráv na stránce.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
let id = prompt('Please input your user name');
let res = await fetch(`/negotiate?id=${id}`);
let data = await res.json();
let ws = new WebSocket(data.url);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
messages.appendChild(m);
};
let message = document.querySelector('#message');
message.addEventListener('keypress', e => {
if (e.charCode !== 13) return;
ws.send(message.value);
message.value = '';
});
})();
</script>
</body>
</html>
Ve výše uvedeném kódu se připojujeme pomocí nativního rozhraní WebSocket API v prohlížeči a používáme WebSocket.send()
k odesílání zpráv a WebSocket.onmessage
naslouchání přijatým zprávám.
Klientské sady SDK můžete také použít k připojení ke službě, což vám umožní automatické opětovné připojení, zpracování chyb a další možnosti.
Teď zbývá ještě jeden krok, aby chat fungoval. Pojďme nakonfigurovat, na jakých událostech záleží a kam se mají události odesílat ve službě Web PubSub.
Nastavení obslužné rutiny události
Obslužnou rutinu události ve službě Web PubSub nastavíme tak, aby službě řekla, kam se mají události odesílat.
Když se webový server spustí místně, jak služba Web PubSub vyvolá localhost, pokud nemá žádný koncový bod přístupný z internetu? Existují obvykle dva způsoby. Jedním z nich je zveřejnění místního hostitele pro veřejnost pomocí některého obecného tunelového nástroje a druhý je použít tunel upws-tunnel k tunelování provozu ze služby Web PubSub prostřednictvím nástroje na místní server.
V této části pomocí Azure CLI nastavíme obslužné rutiny událostí a pomocí tunelu awps-tunnel směrujeme provoz do místního hostitele.
Konfigurace nastavení centra
Šablonu adresy URL jsme nastavili tak, aby používala tunnel
schéma, aby web PubSub směruje zprávy prostřednictvím tunelového awps-tunnel
připojení. Obslužné rutiny událostí je možné nastavit z portálu nebo rozhraní příkazového řádku, jak je popsáno v tomto článku. Tady je nastavíme prostřednictvím rozhraní příkazového řádku. Vzhledem k tomu, že nasloucháme událostem v cestě /eventhandler
jako předchozí sady kroků, nastavíme šablonu url na tunnel:///eventhandler
.
Pomocí příkazu az webpubsub hub az webpubsub hub vytvořte nastavení obslužné rutiny události pro Sample_ChatApp
centrum.
Důležité
Nahraďte <název-jedinečný-prostředek> názvem prostředku Web PubSub vytvořeným z předchozích kroků.
az webpubsub hub create -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected"
Místní spuštění tunelu awps
Stažení a instalace tunelu awps-tunnel
Nástroj běží na Node.js verze 16 nebo vyšší.
npm install -g @azure/web-pubsub-tunnel-tool
Použití připojovací řetězec služby a spuštění
export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080
Spuštění webového serveru
Teď je všechno nastavené. Pojďme spustit webový server a hrát s chatovací aplikací v akci.
Nyní spusťte server pomocí dotnet run --urls http://localhost:8080
příkazu .
Kompletní vzorový kód tohoto kurzu najdete tady.
Otevře záznam typu http://localhost:8080/index.html
. Můžete zadat svoje uživatelské jméno a začít chatovat.
Opožděné ověřování s obslužnou rutinou connect
události
V předchozích částech si ukážeme, jak pomocí koncového bodu vyjednat vrátit adresu URL služby Web PubSub a přístupový token JWT pro klienty pro připojení ke službě Web PubSub. V některých případech můžou například hraniční zařízení s omezenými prostředky upřednostňovat přímé připojení k prostředkům Web PubSub. V takových případech můžete nakonfigurovat connect
obslužnou rutinu události tak, aby opožděně ověřovali klienty, přiřaďte klientům ID uživatele, určete skupiny, ke kterým se klienti připojují, nakonfigurujte oprávnění, která mají klienti, a subprotocol protokolu WebSocket jako odpověď protokolu WebSocket na klienta atd. Podrobnosti najdete v části o připojení specifikace obslužné rutiny události.
Teď použijeme connect
obslužnou rutinu události k dosažení podobného oddílu negotiate .
Aktualizace nastavení centra
Nejprve aktualizujeme nastavení centra tak, aby zahrnovala connect
také obslužnou rutinu událostí, musíme také povolit anonymní připojení, aby se klienti bez přístupového tokenu JWT mohli připojit ke službě.
Pomocí příkazu Azure CLI az webpubsub hub update vytvořte nastavení obslužné rutiny události pro Sample_ChatApp
centrum.
Důležité
Nahraďte <název-jedinečný-prostředek> názvem prostředku Web PubSub vytvořeným z předchozích kroků.
az webpubsub hub update -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --allow-anonymous true --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected" system-event="connect"
Aktualizace upstreamové logiky pro zpracování události připojení
Teď aktualizujeme upstreamovou logiku pro zpracování události připojení. Teď bychom mohli koncový bod vyjednat také odebrat.
Podobně jako vyjednání koncového bodu jako ukázkového účelu čteme ID také z parametrů dotazu. V případě připojení se původní dotaz klienta zachová v textu žádosti o událost připojení.
Uvnitř třídy Sample_ChatApp
přepsání OnConnectAsync()
pro zpracování connect
události:
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override ValueTask<ConnectEventResponse> OnConnectAsync(ConnectEventRequest request, CancellationToken cancellationToken)
{
if (request.Query.TryGetValue("id", out var id))
{
return new ValueTask<ConnectEventResponse>(request.CreateResponse(userId: id.FirstOrDefault(), null, null, null));
}
// The SDK catches this exception and returns 401 to the caller
throw new UnauthorizedAccessException("Request missing id");
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
Aktualizace index.html pro přímé připojení
Teď aktualizujeme webovou stránku tak, aby se přímo připojila ke službě Web PubSub. Jednou z věcí, kterou je třeba zmínit, je, že teď pro účely ukázky je koncový bod služby Web PubSub pevně zakódovaný do klientského kódu, aktualizujte název <the host name of your service>
hostitele služby v následujícím html s hodnotou z vlastní služby. Může být stále užitečné načíst hodnotu koncového bodu služby Web PubSub z vašeho serveru. To vám dává větší flexibilitu a možnosti kontroly, ke které se klient připojuje.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
// sample host: mock.webpubsub.azure.com
let hostname = "<the host name of your service>";
let id = prompt('Please input your user name');
let ws = new WebSocket(`wss://${hostname}/client/hubs/Sample_ChatApp?id=${id}`);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
messages.appendChild(m);
};
let message = document.querySelector('#message');
message.addEventListener('keypress', e => {
if (e.charCode !== 13) return;
ws.send(message.value);
message.value = '';
});
})();
</script>
</body>
</html>
Opětovné spuštění serveru
Teď znovu spusťte server a přejděte na webovou stránku podle pokynů před. Pokud jste zastavili awps-tunnel
, spusťte prosím znovu nástroj tunelu.
Další kroky
V tomto kurzu získáte základní představu o fungování systému událostí ve službě Azure Web PubSub.
Projděte si další kurzy, ve které se dozvíte, jak službu používat.