Samouczek: publikowanie i subskrybowanie komunikatów między klientami protokołu WebSocket przy użyciu podprotocol
W samouczku Tworzenie aplikacji do czatu przedstawiono sposób wysyłania i odbierania danych za pomocą interfejsów API protokołu WebSocket na platformie Azure Web PubSub. Jeśli klient komunikuje się z usługą, nie jest potrzebny żaden protokół. Na przykład można wysłać dowolny typ danych przy użyciu polecenia WebSocket.send()
, a serwer odbiera je tak samo, jak jest. Proces interfejsów API protokołu WebSocket jest łatwy w użyciu, ale funkcjonalność jest ograniczona. Na przykład nie można określić nazwy zdarzenia podczas wysyłania zdarzenia na serwer lub publikowania komunikatu do innych klientów zamiast wysyłania go na serwer. Z tego samouczka dowiesz się, jak za pomocą podprotocol rozszerzyć funkcjonalność klienta.
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Tworzenie wystąpienia usługi Web PubSub
- Generowanie pełnego adresu URL w celu ustanowienia połączenia protokołu WebSocket
- Publikowanie komunikatów między klientami protokołu WebSocket przy użyciu podprotocol
Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto platformy Azure.
Wymagania wstępne
Użyj środowiska powłoki Bash w usłudze Azure Cloud Shell. Aby uzyskać więcej informacji, zobacz Szybki start dotyczący powłoki Bash w usłudze Azure Cloud Shell.
Jeśli wolisz uruchamiać polecenia referencyjne interfejsu wiersza polecenia lokalnie, zainstaluj interfejs wiersza polecenia platformy Azure. Jeśli korzystasz z systemu Windows lub macOS, rozważ uruchomienie interfejsu wiersza polecenia platformy Azure w kontenerze Docker. Aby uzyskać więcej informacji, zobacz Jak uruchomić interfejs wiersza polecenia platformy Azure w kontenerze platformy Docker.
Jeśli korzystasz z instalacji lokalnej, zaloguj się do interfejsu wiersza polecenia platformy Azure za pomocą polecenia az login. Aby ukończyć proces uwierzytelniania, wykonaj kroki wyświetlane w terminalu. Aby uzyskać inne opcje logowania, zobacz Logowanie się przy użyciu interfejsu wiersza polecenia platformy Azure.
Po wyświetleniu monitu zainstaluj rozszerzenie interfejsu wiersza polecenia platformy Azure podczas pierwszego użycia. Aby uzyskać więcej informacji na temat rozszerzeń, zobacz Korzystanie z rozszerzeń w interfejsie wiersza polecenia platformy Azure.
Uruchom polecenie az version, aby znaleźć zainstalowane wersje i biblioteki zależne. Aby uaktualnić do najnowszej wersji, uruchom polecenie az upgrade.
- Ta konfiguracja wymaga wersji 2.22.0 lub nowszej interfejsu wiersza polecenia platformy Azure. W przypadku korzystania z usługi Azure Cloud Shell najnowsza wersja jest już zainstalowana.
Tworzenie wystąpienia usługi Azure Web PubSub
Tworzenie grupy zasobów
Grupa zasobów to logiczny kontener przeznaczony do wdrażania zasobów platformy Azure i zarządzania nimi. Użyj polecenia az group create, aby utworzyć grupę zasobów o nazwie myResourceGroup
w eastus
lokalizacji.
az group create --name myResourceGroup --location EastUS
Tworzenie wystąpienia usługi Web PubSub
Uruchom polecenie az extension add , aby zainstalować lub uaktualnić rozszerzenie webpubsub do bieżącej wersji.
az extension add --upgrade --name webpubsub
Użyj polecenia az webpubsub create interfejsu wiersza polecenia platformy Azure, aby utworzyć internetowy pubSub w utworzonej grupie zasobów. Następujące polecenie tworzy zasób Free Web PubSub w grupie zasobów myResourceGroup w regionie EastUS:
Ważne
Każdy zasób Web PubSub musi mieć unikatową nazwę. Zastąp <ciąg your-unique-resource-name> nazwą usługi Web PubSub w poniższych przykładach.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
Dane wyjściowe tego polecenia pokazują właściwości nowo utworzonego zasobu. Zanotuj dwie poniższe właściwości:
- Nazwa zasobu: nazwa podana powyżej parametru
--name
. - hostName: w przykładzie nazwa hosta to
<your-unique-resource-name>.webpubsub.azure.com/
.
W tym momencie Twoje konto platformy Azure jest jedynym autoryzowanym do wykonywania jakichkolwiek operacji na tym nowym zasobie.
Pobieranie Połączenie ionString do użycia w przyszłości
Ważne
Parametry połączenia zawiera informacje o autoryzacji wymagane przez aplikację w celu uzyskania dostępu do usługi Azure Web PubSub. Klucz dostępu wewnątrz parametry połączenia jest podobny do hasła głównego usługi. W środowiskach produkcyjnych należy zawsze zachować ostrożność w celu ochrony kluczy dostępu. Usługa Azure Key Vault umożliwia bezpieczne zarządzanie kluczami i obracanie ich. Unikaj dystrybuowania kluczy dostępu do innych użytkowników, kodowania ich lub zapisywania ich w dowolnym miejscu w postaci zwykłego tekstu, który jest dostępny dla innych użytkowników. Obracanie kluczy, jeśli uważasz, że mogły one zostać naruszone.
Użyj polecenia az webpubsub key interfejsu wiersza polecenia platformy Azure, aby uzyskać Połączenie ionString usługi. Zastąp <your-unique-resource-name>
symbol zastępczy nazwą wystąpienia usługi Azure Web PubSub.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Skopiuj parametry połączenia do późniejszego użycia.
Skopiuj pobrany Połączenie ionString i użyj go w dalszej części tego samouczka <connection_string>
jako wartości .
Konfigurowanie projektu
Wymagania wstępne
Używanie podprotokolu
Klient może uruchomić połączenie protokołu WebSocket przy użyciu określonego podprotokolu. Usługa Azure Web PubSub obsługuje podprotokol wywoływany json.webpubsub.azure.v1
w celu umożliwienia klientom publikowania/subskrybowania bezpośrednio za pośrednictwem usługi Web PubSub zamiast rundy na serwerze nadrzędnym. Aby uzyskać szczegółowe informacje na temat podprotokolu subprotocol obsługiwanego przez usługę Web PubSub platformy Azure, zobacz subprotocol obsługiwany kod JSON WebSocket.
Jeśli używasz innych nazw protokołów, zostaną one zignorowane przez usługę i przekazywanie do serwera w programie obsługi zdarzeń połączenia, aby można było utworzyć własne protokoły.
Teraz utwórzmy aplikację internetową przy użyciu podprotokolu json.webpubsub.azure.v1
.
Instalowanie zależności
mkdir logstream cd logstream dotnet new web dotnet add package Microsoft.Extensions.Azure dotnet add package Azure.Messaging.WebPubSub
Utwórz stronę serwera do hostowania interfejsu
/negotiate
API i strony internetowej.Zaktualizuj
Program.cs
za pomocą poniższego kodu.- Użyj
AddAzureClients
polecenia , aby dodać klienta usługi i odczytać parametry połączenia z konfiguracji. - Dodaj
app.UseStaticFiles();
element przedapp.Run();
, aby obsługiwać pliki statyczne. - I zaktualizuj
app.MapGet
, aby wygenerować token dostępu klienta przy użyciu/negotiate
żądań.
using Azure.Messaging.WebPubSub; using Microsoft.Extensions.Azure; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAzureClients(s => { s.AddWebPubSubServiceClient(builder.Configuration["Azure:WebPubSub:ConnectionString"], "stream"); }); var app = builder.Build(); app.UseStaticFiles(); app.MapGet("/negotiate", async context => { var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>(); var response = new { url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri }; await context.Response.WriteAsJsonAsync(response); }); app.Run();
- Użyj
Tworzenie strony internetowej
Utwórz stronę HTML z poniższą zawartością i zapisz ją jako
wwwroot/index.html
:<html> <body> <div id="output"></div> <script> (async function () { let res = await fetch('/negotiate') let data = await res.json(); let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1'); ws.onopen = () => { console.log('connected'); }; let output = document.querySelector('#output'); ws.onmessage = event => { let d = document.createElement('p'); d.innerText = event.data; output.appendChild(d); }; })(); </script> </body> </html>
Powyższy kod łączy się z usługą i wyświetla wszelkie komunikaty odebrane na stronie. Główną zmianą jest określenie podprotokolu podczas tworzenia połączenia protokołu WebSocket.
Uruchamianie serwera
Do ustawienia parametry połączenia używamy narzędzia Secret Manager dla platformy .NET Core. Uruchom poniższe polecenie, zastępując
<connection_string>
element pobrany w poprzednim kroku i otwórz http://localhost:5000/index.html w przeglądarce:dotnet user-secrets init dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>" dotnet run
Jeśli używasz przeglądarki Chrome, możesz nacisnąć klawisz F12 lub kliknąć prawym przyciskiem myszy pozycję ->Inspect -Developer Tools (Sprawdź ->Developer Tools) i wybrać kartę Sieć. Załaduj stronę internetową i zobaczysz, że połączenie webSocket zostało nawiązane. Wybierz, aby sprawdzić połączenie protokołu WebSocket. W kliencie zostanie wyświetlony poniższy
connected
komunikat o zdarzeniu. Zobaczysz, że możesz pobraćconnectionId
wygenerowany dla tego klienta.{"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
Widać, że za pomocą podprotocol można uzyskać metadane połączenia, gdy połączenie to connected
.
Klient otrzymuje teraz komunikat JSON zamiast zwykłego tekstu. Komunikat JSON zawiera więcej informacji, takich jak typ i źródło komunikatu. Dzięki temu możesz użyć tych informacji, aby wykonać więcej przetwarzania komunikatu (na przykład wyświetlić komunikat w innym stylu, jeśli pochodzi z innego źródła), które można znaleźć w kolejnych sekcjach.
Publikowanie komunikatów z klienta
W samouczku Tworzenie aplikacji czatu, gdy klient wysyła komunikat za pośrednictwem połączenia WebSocket z usługą Web PubSub, usługa wyzwala zdarzenie użytkownika po stronie serwera. W przypadku podprotocol klient ma więcej funkcji, wysyłając komunikat JSON. Można na przykład publikować komunikaty bezpośrednio z klienta za pośrednictwem usługi Web PubSub do innych klientów.
Jest to przydatne, jeśli chcesz przesyłać strumieniowo dużą ilość danych do innych klientów w czasie rzeczywistym. Użyjmy tej funkcji, aby utworzyć aplikację do przesyłania strumieniowego dzienników, która może przesyłać strumieniowo dzienniki konsoli do przeglądarki w czasie rzeczywistym.
Tworzenie programu przesyłania strumieniowego
Utwórz
stream
program:mkdir stream cd stream dotnet new console
Zaktualizuj
Program.cs
przy użyciu następującej zawartości:using System; using System.Net.Http; using System.Net.WebSockets; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace stream { class Program { private static readonly HttpClient http = new HttpClient(); static async Task Main(string[] args) { // Get client url from remote var stream = await http.GetStreamAsync("http://localhost:5000/negotiate"); var url = (await JsonSerializer.DeserializeAsync<ClientToken>(stream)).url; var client = new ClientWebSocket(); client.Options.AddSubProtocol("json.webpubsub.azure.v1"); await client.ConnectAsync(new Uri(url), default); Console.WriteLine("Connected."); var streaming = Console.ReadLine(); while (streaming != null) { if (!string.IsNullOrEmpty(streaming)) { var message = JsonSerializer.Serialize(new { type = "sendToGroup", group = "stream", data = streaming + Environment.NewLine, }); Console.WriteLine("Sending " + message); await client.SendAsync(Encoding.UTF8.GetBytes(message), WebSocketMessageType.Text, true, default); } streaming = Console.ReadLine(); } await client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default); } private sealed class ClientToken { public string url { get; set; } } } }
W tym miejscu możesz zobaczyć, że istnieje nowa koncepcja "grupa". Grupa to koncepcja logiczna w centrum, w którym można opublikować komunikat w grupie połączeń. W centrum można mieć wiele grup, a jeden klient może jednocześnie subskrybować wiele grup. W przypadku korzystania z podprotocol można publikować tylko w grupie zamiast emitować do całego centrum. Aby uzyskać szczegółowe informacje na temat terminów, zapoznaj się z podstawowymi pojęciami.
Ponieważ w tym miejscu używamy grupy, musimy również zaktualizować stronę
index.html
internetową, aby dołączyć do grupy po nawiązaniu połączenia protokołu WebSocket wewnątrzws.onopen
wywołania zwrotnego.let ackId = 0; ws.onopen = () => { console.log('connected'); ws.send(JSON.stringify({ type: 'joinGroup', group: 'stream', ackId: ++ackId })); };
Klient dołącza do grupy, wysyłając komunikat w
joinGroup
typie.Zaktualizuj również logikę
ws.onmessage
wywołania zwrotnego nieco, aby przeanalizować odpowiedź JSON i wydrukować komunikaty tylko zstream
grupy, tak aby działał jako drukarka strumienia na żywo.ws.onmessage = event => { let message = JSON.parse(event.data); if (message.type === 'message' && message.group === 'stream') { let d = document.createElement('span'); d.innerText = message.data; output.appendChild(d); window.scrollTo(0, document.body.scrollHeight); } };
W celu rozważenia zabezpieczeń klient domyślnie nie może publikować ani subskrybować grupy samodzielnie. Zauważyliśmy więc, że ustawiliśmy
roles
klienta podczas generowania tokenu:Ustaw wartość w przypadku
roles
, gdyGenerateClientAccessUri
w plikuStartup.cs
jak poniżej:service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
Na koniec zastosuj również jakiś styl, aby
index.html
dobrze się wyświetlał.<html> <head> <style> #output { white-space: pre; font-family: monospace; } </style> </head>
Teraz uruchom poniższy kod i wpisz dowolny tekst i są one wyświetlane w przeglądarce w czasie rzeczywistym:
ls -R | dotnet run
# Or call `dir /s /b | dotnet run` when you are using CMD under Windows
Możesz też zwolnić dane, aby zobaczyć, że dane są przesyłane strumieniowo do przeglądarki w czasie rzeczywistym:
for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run
Kompletny przykład kodu tego samouczka można znaleźć tutaj.
Następne kroki
Ten samouczek zawiera podstawowe informacje na temat nawiązywania połączenia z usługą Web PubSub oraz publikowania komunikatów na połączonych klientach przy użyciu podprotocol.
Zapoznaj się z innymi samouczkami, aby dowiedzieć się więcej na temat korzystania z usługi.