Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В руководстве по созданию приложения чата вы узнали, как использовать API WebSocket для отправки и получения данных с помощью Azure Web PubSub. Для обмена данными между клиентом и службой протокол не требуется. Например, можно отправить любой тип данных с помощью WebSocket.send(), и сервер получает их в том же виде. Процесс API WebSocket прост в использовании, но функциональность ограничена. Например, нельзя указать имя события при отправке события на сервер или опубликовать сообщение другим клиентам вместо отправки на сервер. В этом руководстве описано, как использовать подпротокол для расширения функциональности клиента.
В этом руководстве описано следующее:
- Создайте экземпляр службы Web PubSub
- Создание полного URL-адреса для установки подключения WebSocket
- публикация сообщений между клиентами WebSocket с использованием подпротокола.
Если у вас нет аккаунта Azure, создайте бесплатную учетную запись перед началом.
Предварительные требования
Используйте среду Bash в Azure Cloud Shell. Дополнительные сведения см. в статье "Начало работы с Azure Cloud Shell".
Если вы предпочитаете выполнять справочные команды CLI локально, установите Azure CLI. Если вы работаете в Windows или macOS, Azure CLI можно запустить в контейнере Docker. Дополнительные сведения см. в статье Как запустить Azure CLI в контейнере Docker.
Если вы используете локальную установку, выполните вход в Azure CLI с помощью команды az login. Чтобы выполнить аутентификацию, следуйте инструкциям в окне терминала. Сведения о других параметрах входа см. в статье "Проверка подлинности в Azure с помощью Azure CLI".
Установите расширение Azure CLI при первом использовании, когда появится соответствующий запрос. Дополнительные сведения о расширениях см. в статье Использование расширений и управление ими с помощью Azure CLI.
Выполните команду az version, чтобы узнать установленную версию и зависимые библиотеки. Чтобы обновиться до последней версии, выполните команду az upgrade.
- Для этой настройки требуется Azure CLI версии 2.22.0 или выше. Если вы используете Azure Cloud Shell, последняя версия уже установлена.
Внимание
Необработанные строки подключения приводятся в этой статье исключительно в демонстрационных целях.
A строка подключения содержит информацию об авторизации, необходимую вашему приложению для доступа к сервису Azure Web PubSub. Ключ доступа в строка подключения действует как root-пароль для вашего сервиса. В рабочих средах всегда защищать ключи доступа. Используйте Azure Key Vault для безопасного управления ключами и их ротации, а также защиты подключения с помощью WebPubSubServiceClient.
Старайтесь не распространять ключи доступа среди других пользователей, жестко программировать их или где-то сохранять в виде обычного текста в открытом доступе для других пользователей. Смените ключи, если считаете, что они могли быть скомпрометированы.
Создайте экземпляр Azure Web PubSub
Создайте группу ресурсов
Группа ресурсов — это логический контейнер, в котором происходит развертывание ресурсов Azure и управление ими.
Используйте команду az group create, чтобы создать группу ресурсов с именем myResourceGroup в расположенииeastus.
az group create --name myResourceGroup --location EastUS
Создайте экземпляр Web PubSub
Запустите az extension add, чтобы установить или обновить расширение webpubsub до текущей версии.
az extension add --upgrade --name webpubsub
Используйте команду Azure CLI az webpubsub create, чтобы создать ресурс Web PubSub в созданной вами группе ресурсов. Следующая команда создает ресурс Free Web PubSub в группе ресурсов myResourceGroup в EastUS:
Внимание
Каждый ресурс Web PubSub должен иметь уникальное имя. В следующих примерах замените <your-unique-resource-name> именем своей службы Web PubSub.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
В выходных данных команды будут показаны свойства созданного ресурса. Запишите значения двух указанных ниже свойств.
-
Имя ресурса: имя, которое вы ввели для указанного выше параметра
--name. -
hostName: в примере имя узла
<your-unique-resource-name>.webpubsub.azure.com/.
На данном этапе любые операции в этом новом ресурсе могут выполняться только с использованием вашей учетной записи Azure.
Получение ConnectionString для будущего использования
Необработанные строки подключения приводятся в этой статье исключительно в демонстрационных целях. В рабочих средах всегда защищать ключи доступа. Используйте Azure Key Vault для безопасного управления ключами и их ротации, а также защиты подключения с помощью WebPubSubServiceClient.
Выполните команду Azure CLI az webpubsub key, чтобы получить значение ConnectionString службы. Замените заполнитель <your-unique-resource-name> на имя экземпляра Azure Web PubSub.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Скопируйте строку подключения, чтобы использовать её позже.
Скопируйте полученную ConnectionString и используйте её позже в этом руководстве в качестве значения <connection_string>.
Настройка проекта
Предварительные требования
Использование подпротокола
Клиент может установить подключение к WebSocket по определенному подпротоколу. Служба Azure Web PubSub поддерживает подпротокол, называемый json.webpubsub.azure.v1, который позволяет клиентам напрямую публиковать сообщения и подписываться через службу Azure Web PubSub, минуя обращение к вышестоящему серверу. Сведения о подпротоколе см. в статье Поддерживаемый в Azure Web PubSub подпротокол JSON WebSocket.
Если вы используете другие имена протоколов, они будут игнорироваться службой и передаваться на сервер в обработчике событий подключения, позволяя вам создавать собственные протоколы.
Теперь создадим веб-приложение с использованием подпротокола json.webpubsub.azure.v1.
Установка зависимостей
mkdir logstream cd logstream dotnet new web dotnet add package Microsoft.Extensions.Azure dotnet add package Azure.Messaging.WebPubSubСоздайте серверную часть для размещения API
/negotiateи веб-страницы.Измените файл
Program.cs, добавив приведенный ниже код.- Используйте
AddAzureClients, чтобы добавить клиент службы и прочитать строку подключения из конфигурации. - Добавьте
app.UseStaticFiles();передapp.Run();для поддержки статических файлов. - И измените
app.MapGetтак, чтобы он генерировал токен доступа клиента, используя запросы/negotiate.
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();- Используйте
Создание веб-страницы
Создайте HTML-страницу с приведенным ниже содержимым и сохраните ее как
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>Приведенный выше код подключается к службе и выводит любое сообщение, полученное на страницу. Основное изменение заключается в том, что при создании соединения WebSocket мы указываем подпротокол.
Запуск сервера
Мы используем средство Secret Manager для .NET Core, чтобы настроить строку подключения. Выполните приведенную ниже команду, заменив
<connection_string>строкой, полученной на предыдущем шаге, и откройте http://localhost:5000/index.html в браузере.dotnet user-secrets init dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>" dotnet runЕсли вы используете Chrome, вы можете нажать клавишу F12 или щёлкнуть правой кнопкой мыши ->Просмотреть код ->Инструменты разработчика и выбрать вкладку Сеть. Загрузите веб-страницу, и вы увидите, что соединение WebSocket установлено. Выберите подключение WebSocket, чтобы проверить его; ниже видно, что клиент получил сообщение о событии
connected. Как видите, вы можете сгенерироватьconnectionIdдля этого клиента.{"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
Как видите, с помощью подпротокола можно получить метаданные подключения, если оно имеет значение connected.
Теперь клиент получает сообщение JSON вместо обычного текста. Сообщение JSON содержит дополнительные сведения, такие как тип и источник сообщения. Эти сведения можно использовать для дальнейшей обработки сообщения (например, отобразить сообщение в другом стиле, если оно получено из другого источника). Это описано следующих разделах.
Публикация сообщений от клиента
В руководстве по созданию приложения чата, когда клиент отправляет сообщение через подключение WebSocket к службе Web PubSub, служба активирует событие пользователя на стороне сервера. При использовании подпротокол клиент имеет больше функций, отправляя сообщение JSON. Например, вы можете публиковать сообщения непосредственно из клиента через службу Web PubSub другим клиентам.
Это полезно, если требуется потоковая передача большого объема данных другим клиентам в режиме реального времени. Давайте воспользуемся этой возможностью, чтобы создать приложение потоковой передачи журналов, которое может выполнять потоковую передачу журналов консоли в браузер в реальном времени.
Создание программы потоковой передачи
Создайте программу
stream:mkdir stream cd stream dotnet new consoleИзмените
Program.cs, добавив следующее содержимое: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; } } } }Как видите, здесь есть новое понятие «группа». Группа — это логическая концепция в концентраторе, где можно опубликовать сообщение для группы подключений. В концентраторе можно создать несколько групп. Один клиент может одновременно подписаться на несколько групп. При использовании подпротокола можно публиковать сообщения только в группу, а не выполнять широковещательную отправку по всему центру. Сведения о терминах см. в статье об основных понятиях.
Так как мы используем здесь группу, нам также нужно обновить веб-страницу
index.html, чтобы присоединиться к группе, если подключение WebSocket устанавливается в пределах обратного вызоваws.onopen.let ackId = 0; ws.onopen = () => { console.log('connected'); ws.send(JSON.stringify({ type: 'joinGroup', group: 'stream', ackId: ++ackId })); };Как показано, клиент присоединяется к группе, отправляя сообщение типа
joinGroup.Также можно немного обновить логику обратного вызова
ws.onmessage, чтобы проанализировать ответ JSON и вывести сообщения только от группыstream, используя аналог принтера потока в реальном времени.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); } };По соображениям безопасности клиент по умолчанию не может публиковать данные или подписываться на группу. Итак, вы заметили, что при создании токена мы присвоили клиенту
roles:Установите
rolesприGenerateClientAccessUriвStartup.cs, как показано ниже:service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })Наконец, примените нужный стиль к
index.htmlдля отображения в удобном формате.<html> <head> <style> #output { white-space: pre; font-family: monospace; } </style> </head>
Теперь запустите приведенный ниже код и введите любой текст, и они отображаются в браузере в режиме реального времени:
ls -R | dotnet run
# Or call `dir /s /b | dotnet run` when you are using CMD under Windows
Или можно замедлить процесс, чтобы увидеть, как данные в реальном времени потоково передаются в браузер.
for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run
Полный пример кода для этого учебника можно найти здесь.
Следующие шаги
В этом руководстве вы узнаете, как подключиться к службе Web PubSub и как публиковать сообщения в подключенных клиентах с помощью подпротокола.
Ознакомьтесь с другими руководствами, чтобы глубже разобраться в использовании сервиса.