Руководство. Создание приложения чата Blazor Server
В этом учебнике показано, как создать и изменить приложение Blazor Server. Узнайте следующие темы:
- создать простую комнату чата с помощью шаблона приложения Blazor Server;
- работать с компонентами Razor;
- использовать обработку событий и привязку данных в компонентах Razor;
- выполнить быстрое развертывание в Службе приложений Azure с помощью Visual Studio;
- перейти из локальной службы SignalR в Службу Azure SignalR.
Готовы?
Необходимые компоненты
- Установите пакет SDK для .NET Core 3.0 (версия >= 3.0.100)
- Установите Visual Studio 2019 (версия >= 16.3)
Возникли проблемы? Сообщите нам об этом.
Создание локальной комнаты чата в приложении Blazor Server
Начиная с Visual Studio 2019 версии 16.2.0 служба Azure SignalR встроена в процесс публикации веб-приложения, что делает управление зависимостями между веб-приложением и службой SignalR гораздо удобнее. Вы можете работать без изменений кода одновременно:
- в локальном экземпляре SignalR в локальной среде разработки.
- в Служба Azure SignalR для службы приложение Azure.
Создайте приложение чата Blazor.
В Visual Studio выберите Создать проект.
Выберите Приложение Blazor.
Присвойте приложению имя и выберите папку.
Выберите шаблон Серверное приложение Blazor.
Примечание.
Убедитесь, что вы уже установили пакет SDK для .NET Core 3.0 (или более новой версии), что позволит Visual Studio правильно распознавать требуемую версию .NET Framework.
Вы также можете создать проект, выполнив
dotnet new
команду в CLI .Net:dotnet new blazorserver -o BlazorChat
Добавьте новый файл C# с именем
BlazorChatSampleHub.cs
и создайте для приложения чата новый классBlazorChatSampleHub
, производный от классаHub
. Дополнительные сведения о создании концентраторов см. в статье Создание и использование концентраторов.using System; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace BlazorChat { public class BlazorChatSampleHub : Hub { public const string HubUrl = "/chat"; public async Task Broadcast(string username, string message) { await Clients.All.SendAsync("Broadcast", username, message); } public override Task OnConnectedAsync() { Console.WriteLine($"{Context.ConnectionId} connected"); return base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception e) { Console.WriteLine($"Disconnected {e?.Message} {Context.ConnectionId}"); await base.OnDisconnectedAsync(e); } } }
Добавьте конечную точку для концентратора в методе
Startup.Configure()
.app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl); });
Установите пакет
Microsoft.AspNetCore.SignalR.Client
для использования клиента SignalR.dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
Чтобы реализовать клиент SignalR, создайте новый компонент Razor, который вызывается
ChatRoom.razor
в папкеPages
. Используйте файл ChatRoom.razor или выполните следующие действия:Добавьте директиву
@page
и операторы using. Используйте директиву@inject
для внедрения службыNavigationManager
.@page "/chatroom" @inject NavigationManager navigationManager @using Microsoft.AspNetCore.SignalR.Client;
В разделе
@code
добавьте указанные ниже элементы в новый клиент SignalR для отправки и получения сообщений.@code { // flag to indicate chat status private bool _isChatting = false; // name of the user who will be chatting private string _username; // on-screen message private string _message; // new message input private string _newMessage; // list of messages in chat private List<Message> _messages = new List<Message>(); private string _hubUrl; private HubConnection _hubConnection; public async Task Chat() { // check username is valid if (string.IsNullOrWhiteSpace(_username)) { _message = "Please enter a name"; return; }; try { // Start chatting and force refresh UI. _isChatting = true; await Task.Delay(1); // remove old messages if any _messages.Clear(); // Create the chat client string baseUrl = navigationManager.BaseUri; _hubUrl = baseUrl.TrimEnd('/') + BlazorChatSampleHub.HubUrl; _hubConnection = new HubConnectionBuilder() .WithUrl(_hubUrl) .Build(); _hubConnection.On<string, string>("Broadcast", BroadcastMessage); await _hubConnection.StartAsync(); await SendAsync($"[Notice] {_username} joined chat room."); } catch (Exception e) { _message = $"ERROR: Failed to start chat client: {e.Message}"; _isChatting = false; } } private void BroadcastMessage(string name, string message) { bool isMine = name.Equals(_username, StringComparison.OrdinalIgnoreCase); _messages.Add(new Message(name, message, isMine)); // Inform blazor the UI needs updating InvokeAsync(StateHasChanged); } private async Task DisconnectAsync() { if (_isChatting) { await SendAsync($"[Notice] {_username} left chat room."); await _hubConnection.StopAsync(); await _hubConnection.DisposeAsync(); _hubConnection = null; _isChatting = false; } } private async Task SendAsync(string message) { if (_isChatting && !string.IsNullOrWhiteSpace(message)) { await _hubConnection.SendAsync("Broadcast", _username, message); _newMessage = string.Empty; } } private class Message { public Message(string username, string body, bool mine) { Username = username; Body = body; Mine = mine; } public string Username { get; set; } public string Body { get; set; } public bool Mine { get; set; } public bool IsNotice => Body.StartsWith("[Notice]"); public string CSS => Mine ? "sent" : "received"; } }
Добавьте разметку пользовательского интерфейса перед разделом
@code
для взаимодействия с клиентом SignalR.<h1>Blazor SignalR Chat Sample</h1> <hr /> @if (!_isChatting) { <p> Enter your name to start chatting: </p> <input type="text" maxlength="32" @bind="@_username" /> <button type="button" @onclick="@Chat"><span class="oi oi-chat" aria-hidden="true"></span> Chat!</button> // Error messages @if (_message != null) { <div class="invalid-feedback">@_message</div> <small id="emailHelp" class="form-text text-muted">@_message</small> } } else { // banner to show current user <div class="alert alert-secondary mt-4" role="alert"> <span class="oi oi-person mr-2" aria-hidden="true"></span> <span>You are connected as <b>@_username</b></span> <button class="btn btn-sm btn-warning ml-md-auto" @onclick="@DisconnectAsync">Disconnect</button> </div> // display messages <div id="scrollbox"> @foreach (var item in _messages) { @if (item.IsNotice) { <div class="alert alert-info">@item.Body</div> } else { <div class="@item.CSS"> <div class="user">@item.Username</div> <div class="msg">@item.Body</div> </div> } } <hr /> <textarea class="input-lg" placeholder="enter your comment" @bind="@_newMessage"></textarea> <button class="btn btn-default" @onclick="@(() => SendAsync(_newMessage))">Send</button> </div> }
Обновите компонент
NavMenu.razor
и вставьте новый компонентNavLink
для связи с комнатой чата в разделеNavMenuCssClass
.<li class="nav-item px-3"> <NavLink class="nav-link" href="chatroom"> <span class="oi oi-chat" aria-hidden="true"></span> Chat room </NavLink> </li>
Добавьте в файл
site.css
несколько классов CSS для стилизации элементов пользовательского интерфейса на странице чата./* improved for chat text box */ textarea { border: 1px dashed #888; border-radius: 5px; width: 80%; overflow: auto; background: #f7f7f7 } /* improved for speech bubbles */ .received, .sent { position: relative; font-family: arial; font-size: 1.1em; border-radius: 10px; padding: 20px; margin-bottom: 20px; } .received:after, .sent:after { content: ''; border: 20px solid transparent; position: absolute; margin-top: -30px; } .sent { background: #03a9f4; color: #fff; margin-left: 10%; top: 50%; text-align: right; } .received { background: #4CAF50; color: #fff; margin-left: 10px; margin-right: 10%; } .sent:after { border-left-color: #03a9f4; border-right: 0; right: -20px; } .received:after { border-right-color: #4CAF50; border-left: 0; left: -20px; } /* div within bubble for name */ .user { font-size: 0.8em; font-weight: bold; color: #000; } .msg { /*display: inline;*/ }
Чтобы запустить приложение, нажмите клавишу F5. Теперь можно начать чат:
Возникли проблемы? Сообщите нам об этом.
Публикация в Azure
При развертывании приложения Blazor в Службе приложений Azure рекомендуется использовать Службу Azure SignalR. Служба Azure SignalR позволяет масштабировать приложение Blazor Server до большого количества одновременных подключений SignalR. Кроме того, глобальный охват службы SignalR и ее высокопроизводительные центры обработки данных обеспечивают низкую задержку благодаря доступности в разных регионах.
Внимание
В приложении Blazor Server состояния пользовательского интерфейса сохраняются на стороне сервера, то есть для сохранения состояния требуется "прикрепленный" серверный сеанс. Если у вас один сервер приложений, закрепление сеансов реализовано естественным образом. Однако если несколько серверов приложений используются, переговоры клиента и подключение могут быть перенаправлены на разные серверы, что может привести к несогласованному управлению состояниями пользовательского интерфейса в приложении Blazor. Поэтому рекомендуется включить липкие сеансы сервера, как показано в appsettings.json:
"Azure:SignalR:ServerStickyMode": "Required"
Щелкните проект правой кнопкой мыши и выберите Опубликовать. Используйте следующие параметры:
- Цель: Azure
- Конкретизированный целевой объект: поддерживаются все типы Службы приложений Azure.
- Служба приложений: создайте или выберите экземпляр Службы приложений.
Добавьте зависимости Службы Azure SignalR.
После создания профиля публикации в разделе Зависимости службы появится сообщение с рекомендацией добавить службу Azure SignalR. Щелкните Настроить, чтобы создать новую или выбрать существующую Службу Azure SignalR на панели.
Зависимость службы выполняет следующие действия, чтобы приложение автоматически переключалось на Служба Azure SignalR, когда в Azure:
- Обновите
HostingStartupAssembly
, чтобы использовать Службу Azure SignalR. - Добавьте ссылку на пакет NuGet для Службы Azure SignalR.
- Обновите свойства профиля таким образом, чтобы сохранить параметры зависимости.
- Выберите и настройте хранилище секретов.
- Добавьте конфигурацию в файл appsettings.json, чтобы задать в качестве цели приложения Службу Azure SignalR.
- Обновите
Публикация приложения.
Теперь приложение готово к публикации. После завершения публикации приложение автоматически запускается в браузере.
Примечание.
Для запуска приложения может потребоваться некоторое время из-за задержки запуска развертывания Службы приложений Azure. Вы можете использовать средства отладчика браузера (как правило, они вызываются клавишей F12), чтобы убедиться, что трафик перенаправляется в Службу Azure SignalR.
Возникли проблемы? Сообщите нам об этом.
Включение Службы Azure SignalR в локальной среде разработки
Добавьте ссылку на пакет SDK Azure SignalR с помощью команды ниже.
dotnet add package Microsoft.Azure.SignalR
Добавьте вызов
AddAzureSignalR()
,Startup.ConfigureServices()
как показано в следующем примере:public void ConfigureServices(IServiceCollection services) { ... services.AddSignalR().AddAzureSignalR(); ... }
Настройте строку подключения Службы SignalR Azure в файле appsettings.js либо с помощью диспетчера секретов.
Примечание.
Шаг 2 можно заменить настройкой стартовых сборок размещения для использования пакета SDK SignalR.
Добавьте конфигурацию для включения Службы Azure SignalR в файл appsettings.json:
"Azure": { "SignalR": { "Enabled": true, "ConnectionString": <your-connection-string> } }
Настройте стартовую сборку размещения для использования пакета SDK для Azure SignalR. Отредактируйте файл launchSettings.json и добавьте в
environmentVariables
конфигурацию, как в примере ниже:"environmentVariables": { ..., "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.Azure.SignalR" }
Возникли проблемы? Сообщите нам об этом.
Очистка ресурсов
Чтобы очистить ресурсы, созданные при работе с этим руководством, удалите группу ресурсов через портал Azure.
Дополнительные ресурсы
Следующие шаги
Из этого руководства вы узнали, как:
- создать простую комнату чата с помощью шаблона приложения Blazor Server;
- работать с компонентами Razor;
- использовать обработку событий и привязку данных в компонентах Razor;
- выполнить быстрое развертывание в Службе приложений Azure с помощью Visual Studio;
- перейти из локальной службы SignalR в Службу Azure SignalR.
Подробнее о высоком уровне доступности: