Megosztás a következőn keresztül:


Oktatóanyag: Csevegőalkalmazás létrehozása az Azure Web PubSub szolgáltatással

Az Üzenet közzététele és előfizetése oktatóanyagban megismerheti az üzenetek közzétételének és előfizetésének alapjait az Azure Web PubSub használatával. Ebben az oktatóanyagban megismerheti az Azure Web PubSub eseményrendszerét, és segítségével egy teljes webalkalmazást hozhat létre valós idejű kommunikációs funkciókkal.

Ebben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • Web PubSub szolgáltatáspéldány létrehozása
  • Az Azure Web PubSub eseménykezelő beállításainak konfigurálása
  • Hanlde-események az alkalmazáskiszolgálón, és valós idejű csevegőalkalmazás létrehozása

Ha nem rendelkezik Azure-előfizetéssel, első lépésként hozzon létre egy ingyenes Azure-fiókot.

Előfeltételek

  • Ehhez a beállításhoz az Azure CLI 2.22.0-s vagy újabb verziója szükséges. Az Azure Cloud Shell használata esetén a legújabb verzió már telepítve van.

Azure Web PubSub-példány létrehozása

Erőforráscsoport létrehozása

Az erőforráscsoport olyan logikai tároló, amelybe a rendszer üzembe helyezi és kezeli az Azure-erőforrásokat. Az az group create paranccsal hozzon létre egy, a eastus helyen elnevezett myResourceGroup erőforráscsoportot.

az group create --name myResourceGroup --location EastUS

Web PubSub-példány létrehozása

Futtassa az az extension add parancsot a webpubsub bővítmény telepítéséhez vagy frissítéséhez az aktuális verzióra.

az extension add --upgrade --name webpubsub

Az Azure CLI az webpubsub create paranccsal hozzon létre egy Web PubSub-t a létrehozott erőforráscsoportban. Az alábbi parancs létrehoz egy ingyenes Web PubSub-erőforrást a myResourceGroup erőforráscsoportban az EastUS-ban:

Fontos

Minden Web PubSub-erőforrásnak egyedi névvel kell rendelkeznie. Az alábbi példákban cserélje le <az egyedi erőforrás nevét> a Web PubSub nevére.

az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1

A parancs kimenete az újonnan létrehozott erőforrás tulajdonságait jeleníti meg. Jegyezze fel az alábbi két tulajdonságot:

  • Erőforrás neve: A fenti paraméternek --name megadott név.
  • hostName: A példában a gazdagép neve .<your-unique-resource-name>.webpubsub.azure.com/

Ezen a ponton az Azure-fiók az egyetlen jogosult az új erőforráson végzett műveletek végrehajtására.

A Csatlakozás ionString lekérése jövőbeli használatra

Fontos

A kapcsolati sztring tartalmazzák azokat az engedélyezési információkat, amelyekre az alkalmazásnak szüksége van az Azure Web PubSub szolgáltatás eléréséhez. A kapcsolati sztring belüli hozzáférési kulcs hasonló a szolgáltatás gyökérjelszójához. Éles környezetben mindig ügyeljen a hozzáférési kulcsok védelmére. Az Azure Key Vault használatával biztonságosan kezelheti és elforgathatja a kulcsokat. Kerülje a hozzáférési kulcsok más felhasználók számára való terjesztését, a szigorú kódolást, illetve a mások számára hozzáférhető egyszerű szövegek mentését. Ha úgy véli, hogy illetéktelenek lettek, forgassa el a kulcsokat.

A szolgáltatás Csatlakozás ionString parancsának lekéréséhez használja az Azure CLI az webpubsub billentyűkombinációt. Cserélje le a <your-unique-resource-name> helyőrzőt az Azure Web PubSub-példány nevére.

az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv

Másolja a kapcsolati sztring későbbi használatra.

Másolja ki a beolvasott Csatlakozás ionStringet, és állítsa be környezeti változóbaWebPubSubConnectionString, amelyet az oktatóanyag később felolvas. Cserélje le <connection-string> az alábbiakat a lekért Csatlakozás ionStringre.

export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>

A projekt előkészítése

Előfeltételek

Az alkalmazás létrehozása

Az Azure Web PubSubban két szerepkör van, a kiszolgáló és az ügyfél. Ez a fogalom hasonló a webalkalmazások kiszolgálói és ügyfélszerepköreihez. A kiszolgáló feladata az ügyfelek kezelése, az ügyfélüzenetek figyelése és megválaszolása. Az ügyfél feladata, hogy elküldje és fogadja a felhasználó üzeneteit a kiszolgálóról, és megjelenítse őket a végfelhasználó számára.

Ebben az oktatóanyagban egy valós idejű csevegő webalkalmazást hozunk létre. Egy valódi webalkalmazásban a kiszolgáló felelőssége az ügyfelek hitelesítését és a statikus weblapok kiszolgálását is magában foglalja az alkalmazás felhasználói felületén.

A ASP.NET Core 8-at használjuk a weblapok üzemeltetéséhez és a bejövő kérések kezeléséhez.

Először hozzunk létre egy ASP.NET Core-webalkalmazást egy chatapp mappában.

  1. Hozzon létre egy új webalkalmazást.

    mkdir chatapp
    cd chatapp
    dotnet new web
    
  2. Adjon hozzá app.UseStaticFiles() Program.cs a statikus weblapok üzemeltetésének támogatásához.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.UseStaticFiles();
    
    app.Run();
    
  3. Hozzon létre egy HTML-fájlt, és mentse azt úgy, ahogyan wwwroot/index.htmlazt később a csevegőalkalmazás felhasználói felületén használjuk.

    <html>
      <body>
        <h1>Azure Web PubSub Chat</h1>
      </body>
    </html>
    

A kiszolgálót a böngészőben futtatva dotnet run --urls http://localhost:8080 és elérve http://localhost:8080/index.html tesztelheti.

Egyeztetési végpont hozzáadása

Az oktatóanyag közzétételi és előfizetési üzenetében az előfizető közvetlenül kapcsolati sztring használ fel. Egy valós alkalmazásban nem biztonságos megosztani a kapcsolati sztring egyetlen ügyféllel sem, mert kapcsolati sztring nagy jogosultsággal rendelkezik bármilyen művelet végrehajtásához a szolgáltatásban. Most hozzuk létre, hogy a kiszolgáló a kapcsolati sztring használhassa, és hozzon létre egy végpontot negotiate az ügyfél számára a teljes URL-cím lekéréséhez hozzáférési jogkivonattal. Így a kiszolgáló a végpont előtt hitelesítési köztes szoftvereket adhat hozzá a negotiate jogosulatlan hozzáférés megakadályozása érdekében.

Először telepítse a függőségeket.

dotnet add package Microsoft.Azure.WebPubSub.AspNetCore

Most adjunk hozzá egy végpontot /negotiate az ügyfélhez, amely meghívja a jogkivonatot.

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>() a szolgáltatásügyfél WebPubSubServiceClient<THub>injektálására szolgál, amellyel a tárgyalási lépésben ügyfélkapcsolati jogkivonatot hozhatunk létre, valamint a központi metódusokban a szolgáltatás REST API-jait hívhatjuk meg a központi események aktiválásakor. Ez a jogkivonat-létrehozási kód hasonló a közzétételi és feliratkozási üzenet oktatóanyagában használt kódhoz, kivéve, hogy a jogkivonat létrehozásakor még egy argumentumot (userId) adunk át. A felhasználói azonosítóval azonosíthatja az ügyfél identitását, így amikor üzenetet kap, tudja, hogy honnan származik az üzenet.

A kód beolvassa kapcsolati sztring az előző lépésben beállított környezeti változóból.WebPubSubConnectionString

Futtassa újra a kiszolgálót a következő használatával dotnet run --urls http://localhost:8080: .

Ezt az API-t a hozzáféréssel http://localhost:8080/negotiate?id=user1 tesztelheti, és egy hozzáférési jogkivonattal megadja az Azure Web PubSub teljes URL-címét.

Események kezelése

Az Azure Web PubSubban, ha bizonyos tevékenységek történnek az ügyféloldalon (például egy ügyfél csatlakozik, csatlakozik, megszakadt, vagy egy ügyfél üzeneteket küld), a szolgáltatás értesítéseket küld a kiszolgálónak, hogy reagálni tudjon ezekre az eseményekre.

Az események webhook formájában érkeznek a kiszolgálóra. A Webhookot az alkalmazáskiszolgáló szolgáltatja és teszi közzé, és regisztrálja az Azure Web PubSub szolgáltatás oldalán. A szolgáltatás esemény esetén meghívja a webhookokat.

Az Azure Web PubSub a CloudEventst követi az eseményadatok leírásához.

Az alábbiakban rendszereseményeket kezelünk connected , amikor egy ügyfél csatlakozik, és kezeli message a felhasználói eseményeket, amikor egy ügyfél üzeneteket küld a csevegőalkalmazás létrehozásához.

Az előző lépésben telepített AspNetCore-hoz Microsoft.Azure.WebPubSub.AspNetCore készült Web PubSub SDK is segíthet elemezni és feldolgozni a CloudEvents-kérelmeket.

Először vegyen fel eseménykezelőket.app.Run() Adja meg az események végponti elérési útját, mondjuk /eventhandler.

app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();

Most az előző lépésben létrehozott osztályon Sample_ChatApp belül adjon hozzá egy konstruktort WebPubSubServiceClient<Sample_ChatApp> a Web PubSub szolgáltatás meghívásához használt konstruktorhoz. Az OnConnectedAsync() esemény aktiválásakor connected OnMessageReceivedAsync() pedig az ügyféltől érkező üzenetek kezelésére is válaszolhat.

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();
    }
}

A fenti kódban a szolgáltatásügyfél használatával küldünk egy JSON formátumú értesítési üzenetet, amellyel az összes felhasználó csatlakozik SendToAllAsync.

A weblap frissítése

Most frissítsünk index.html , hogy hozzáadjuk a logikát a csatlakozáshoz, az üzenetküldéshez és a fogadott üzenetek megjelenítéséhez a lapon.

<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>

A fenti kódban láthatja, hogy a böngészőben a natív WebSocket API-val csatlakozunk, és üzenetküldésre és WebSocket.onmessage a fogadott üzenetek figyelésére szolgálWebSocket.send().

Ügyféloldali SDK-k használatával is csatlakozhat a szolgáltatáshoz, ami lehetővé teszi az automatikus újracsatlakozás, a hibakezelés és egyebek használatát.

Most már csak egy lépés maradt a csevegés működéséhez. Konfiguráljuk, hogy mely események érdekelnek, és hová küldjük az eseményeket a Web PubSub szolgáltatásban.

Az eseménykezelő beállítása

A Web PubSub szolgáltatásban az eseménykezelőt úgy állítottuk be, hogy megmondja a szolgáltatásnak, hová küldje az eseményeket.

Amikor a webkiszolgáló helyileg fut, a Web PubSub szolgáltatás hogyan hívja meg a localhostot, ha nincs internethez elérhető végpontja? Általában kétféleképpen lehet. Az egyik, hogy nyilvánosan elérhetővé teszi a localhostot egy általános alagúteszköz használatával, a másik pedig az awps-tunnel használata a Web PubSub szolgáltatásból a helyi kiszolgáló felé történő forgalom bújtatásához.

Ebben a szakaszban az Azure CLI használatával állítjuk be az eseménykezelőket, és awps-tunnel használatával irányítjuk a forgalmat a localhost felé.

Központbeállítások konfigurálása

Az URL-sablont séma használatára tunnel állítottuk be, hogy a Web PubSub az üzeneteket az awps-tunnelalagútkapcsolaton keresztül irányozza át. Az eseménykezelők beállíthatók a portálról vagy a parancssori felületről a jelen cikkben leírtak szerint, itt pedig a parancssori felület használatával állíthatjuk be. Mivel az előző lépéskészletekben az elérési úton /eventhandler lévő eseményeket figyeljük, az URL-sablont a következőre tunnel:///eventhandlerállítjuk be: .

Az Azure CLI az webpubsub hub létrehozási parancsával hozza létre a központ eseménykezelő beállításait Sample_ChatApp .

Fontos

Cserélje le <az egyedi erőforrás nevét> az előző lépésekből létrehozott Web PubSub-erőforrás nevére.

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"

Az awps-tunnel helyi futtatása

Az awps-tunnel letöltése és telepítése

Az eszköz Node.js 16-os vagy újabb verzión fut.

npm install -g @azure/web-pubsub-tunnel-tool

A szolgáltatás kapcsolati sztring használata és futtatása

export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080

A webkiszolgáló futtatása

Most már minden be van állítva. Futtassuk a webkiszolgálót, és játsszunk a csevegőalkalmazással működés közben.

Most futtassa a kiszolgálót dotnet run --urls http://localhost:8080a .

Az oktatóanyag teljes kódmintája itt található.

Nyílt http://localhost:8080/index.html. Megadhatja a felhasználónevet, és megkezdheti a csevegést.

Lazy Auth with connect event handler

Az előző szakaszokban bemutatjuk, hogyan használhatja az egyeztetési végpontot a Web PubSub szolgáltatás URL-címének és az ügyfelek JWT hozzáférési jogkivonatának visszaadásához a Web PubSub szolgáltatáshoz való csatlakozáshoz. Bizonyos esetekben, például a korlátozott erőforrásokkal rendelkező peremeszközök esetében az ügyfelek szívesebben csatlakoznak közvetlenül a Web PubSub-erőforrásokhoz. Ilyen esetekben konfigurálhatja connect az eseménykezelőt az ügyfelek lusta hitelesítésére, felhasználói azonosító hozzárendelésére az ügyfelekhez, megadhatja azokat a csoportokat, amelyekhez az ügyfelek csatlakoznak a csatlakozás után, konfigurálhatja az ügyfelek engedélyeit és a WebSocket-alprotocolt az ügyfélre adott WebSocket-válaszként stb. A részletekért tekintse meg az eseménykezelő specifikációjának csatlakoztatását.

Most használjuk connect az eseménykezelőt a tárgyalási szakaszhoz hasonló eredmény eléréséhez.

Központ beállításainak frissítése

Először frissítsük a központ beállításait úgy, hogy az eseménykezelőt is tartalmazza connect , engedélyezni kell a névtelen csatlakozást is, hogy a JWT hozzáférési jogkivonattal nem rendelkező ügyfelek kapcsolódhassanak a szolgáltatáshoz.

Az Azure CLI az webpubsub hub frissítési parancsával hozza létre a központ eseménykezelő beállításait Sample_ChatApp .

Fontos

Cserélje le <az egyedi erőforrás nevét> az előző lépésekből létrehozott Web PubSub-erőforrás nevére.

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"

A kapcsolati esemény kezeléséhez frissítse a felsőbb rétegbeli logikát

Most frissítsük a felsőbb rétegbeli logikát a kapcsolódási esemény kezeléséhez. A tárgyalási végpontot most is eltávolíthatjuk.

Hasonlóan ahhoz, amit a letárgyalási végponton demóként csinálunk, a lekérdezési paraméterekből is beolvasjuk az azonosítót. Kapcsolódási esemény esetén az eredeti ügyfél-lekérdezés megmarad a connect esemény-újrakérés törzsében.

Az osztályon Sample_ChatAppbelül felülbírálás OnConnectAsync() az esemény kezeléséhez connect :

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();
    }
}

Index.html frissítése a közvetlen csatlakozáshoz

Most frissítsük a weblapot, hogy közvetlenül csatlakozzunk a Web PubSub szolgáltatáshoz. Egy dolog, amit meg kell említeni, hogy a Web PubSub szolgáltatásvégpont most már nehezen kódolt az ügyfélkódba, kérjük, frissítse a szolgáltatás állomásnevét <the host name of your service> az alábbi html-ben a saját szolgáltatása értékével. Továbbra is hasznos lehet lekérni a Web PubSub szolgáltatás végpontértékét a kiszolgálóról, így nagyobb rugalmasságot és szabályozhatóságot biztosít arra a helyre, amelyhez az ügyfél csatlakozik.

<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>

A kiszolgáló újrafuttatása

Most futtassa újra a kiszolgálót , és keresse fel a weblapot az előző utasításoknak megfelelően. Ha leálltawps-tunnel, futtassa újra az alagúteszközt is.

Következő lépések

Ez az oktatóanyag alapszintű képet nyújt az eseményrendszer működéséről az Azure Web PubSub szolgáltatásban.

A szolgáltatás használatának további megismeréséhez tekintse meg a többi oktatóanyagot.