Membangun aplikasi obrolan Blazor Server

Tutorial ini menunjukkan kepada Anda cara membuat dan memodifikasi aplikasi Blazor Server. Anda akan mempelajari cara:

  • Bangun ruang obrolan sederhana dengan templat aplikasi Blazor Server.
  • Bekerja dengan komponen Razor.
  • Gunakan penanganan peristiwa dan pengikatan data pada komponen Razor.
  • Terapkan cepat ke Azure App Service di Visual Studio.
  • Migrasi dari SignalR lokal ke Layanan SignalR Azure.

Siap untuk mulai?

Prasyarat

Mengalami masalah? Beri tahu kami.

Membangun ruang obrolan lokal di aplikasi Blazor Server

Dimulai di Visual Studio 2019 versi 16.2.0, Azure SignalR Service dibangun ke dalam proses publikasi aplikasi web untuk membuat pengelolaan dependensi antara aplikasi web dan layanan SignalR jauh lebih nyaman. Anda dapat bekerja di instans SignalR lokal di lingkungan pengembangan lokal dan bekerja di Azure SignalR Service untuk Azure App Service secara bersamaan tanpa perubahan kode apa pun.

  1. Membuat aplikasi obrolan Blazor:

    1. Di Visual Studio, pilih Buat proyek baru.

    2. Pilih Aplikasi Blazor.

    3. Beri nama aplikasi dan pilih folder.

    4. Pilih templat Aplikasi Blazor Server.

      Catatan

      Pastikan Anda telah menginstal .NET Core SDK 3.0+ untuk mengaktifkan Visual Studio untuk mengenali kerangka kerja target dengan benar.

      In Create a new project, select the Blazor app template.

    5. Anda juga dapat membuat proyek dengan menjalankan dotnet new perintah di .NET CLI:

      dotnet new blazorserver -o BlazorChat
      
  2. Tambahkan file C# baru yang dipanggilBlazorChatSampleHub.cs dan buat kelas baru BlazorChatSampleHub yang berasal dari Hub kelas untuk aplikasi obrolan. Untuk informasi selengkapnya tentang membuat hub, lihat Membuat dan Menggunakan 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);
            }
        }
    }
    
  3. Tambahkan titik akhir untuk hub dalam Startup.Configure() metode.

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Instal Microsoft.AspNetCore.SignalR.Client paket untuk menggunakan klien SignalR.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Buat komponen Razor baru yang dipanggil ChatRoom.razor di bawah Pages folder untuk mengimplementasikan klien SignalR. Ikuti langkah-langkah di bawah ini atau gunakan file ChatRoom.razor.

    1. Tambahkan @page direktif dan pernyataan penggunaan. Gunakan @inject direktif untuk menyuntikkan NavigationManager layanan.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. Di bagian @code tersebut, tambahkan anggota berikut ke klien SignalR baru untuk mengirim dan menerima pesan.

      @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";
          }
      }
      
    3. Tambahkan markup UI sebelum @code bagian untuk berinteraksi dengan klien 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>
      }
      
  6. Perbarui NavMenu.razor komponen untuk menyisipkan komponen baru untuk NavLink ditautkan ke ruang obrolan di bawah 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>
    
  7. Tambahkan beberapa kelas CSS ke site.css file untuk menata elemen UI di halaman obrolan.

    /* 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;*/
    }
    
  8. Tekan F5 untuk menjalankan aplikasi. Sekarang, Anda dapat memulai obrolan:

    An animated chat between Bob and Alice is shown. Alice says Hello, Bob says Hi.

Mengalami masalah? Beri tahu kami.

Menerbitkan ke Azure

Saat Anda menggunakan aplikasi Blazor ke Azure App Service, kami sarankan Anda menggunakan Azure SignalR Service. Azure SignalR Service memungkinkan peningkatan skala aplikasi Blazor Server ke sejumlah besar koneksi SignalR bersamaan. Selain itu, jangkauan global layanan SignalR dan pusat data berkinerja tinggi secara signifikan membantu mengurangi latensi karena geografi.

Penting

Dalam aplikasi Blazor Server, status UI dipertahankan di sisi server, yang berarti sesi server lengket diperlukan untuk mempertahankan status. Jika ada satu server aplikasi, sesi lengket dipastikan berdasarkan desain. Namun, jika ada beberapa server aplikasi, ada kemungkinan bahwa negosiasi dan koneksi klien dapat pergi ke server yang berbeda yang dapat menyebabkan manajemen status UI yang tidak konsisten di aplikasi Blazor. Oleh karena itu, disarankan untuk mengaktifkan sesi server lengket seperti yang ditunjukkan di bawah ini appsettings.json:

"Azure:SignalR:ServerStickyMode": "Required"
  1. Klik kanan proyek dan buka Terbitkan. Gunakan pengaturan berikut:

    • Target: Azure
    • Target spesifik: Semua jenis Azure App Service didukung.
    • App Service: Membuat atau memilih instans App Service.

    The animation shows selection of Azure as target, and then Azure App Serice as specific target.

  2. Tambahkan dependensi Azure SignalR Service.

    Setelah pembuatan profil publikasi, Anda dapat melihat pesan rekomendasi untuk menambahkan Azure SignalR Service di bawah Dependensi Layanan. Pilih Konfigurasikan untuk membuat yang baru atau pilih Azure SignalR Service yang sudah ada di panel.

    On Publish, the link to Configure is highlighted.

    Dependensi layanan akan melakukan aktivitas berikut untuk memungkinkan aplikasi Anda beralih secara otomatis ke Azure SignalR Service saat di Azure:

    • Pembaruan HostingStartupAssembly untuk menggunakan Azure SignalR Service.
    • Tambahkan referensi paket Azure SignalR Service NuGet.
    • Perbarui properti profil untuk menyimpan pengaturan dependensi.
    • Konfigurasikan penyimpanan rahasia sesuai pilihan Anda.
    • Tambahkan konfigurasi dalam appsettings.json membuat aplikasi Anda menargetkan Azure SignalR Service.

    On Summary of changes, the checkboxes are used to select all dependencies.

  3. Memublikasikan aplikasi.

    Sekarang aplikasi siap untuk dipublikasikan. Setelah proses penerbitan selesai, aplikasi secara otomatis diluncurkan di browser.

    Catatan

    Aplikasi mungkin memerlukan waktu untuk memulai karena latensi mulai penerapan Azure App Service. Anda dapat menggunakan alat debugger browser (biasanya dengan menekan F12)untuk memastikan bahwa lalu lintas telah dialihkan ke Azure SignalR Service.

    Blazor SignalR Chat Sample has a text box for your name, and a Chat! button to start a chat.

Mengalami masalah? Beri tahu kami.

Aktifkan Azure SignalR Service untuk pengembangan lokal

  1. Tambahkan referensi ke Azure SignalR SDK menggunakan perintah berikut.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Tambahkan panggilan ke AddAzureSignalR() dalam Startup.ConfigureServices() seperti yang ditunjukkan di bawah ini.

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Konfigurasikan string koneksi Azure SignalR Service baik di appsettings.json atau dengan menggunakan alat Secret Manager.

Catatan

Langkah 2 dapat diganti dengan mengonfigurasi Hosting Startup Assemblies untuk menggunakan SignalR SDK.

  1. Tambahkan konfigurasi untuk mengaktifkan Azure SignalR Service di appsettings.json:

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string>       
      }
    }
    
    
  2. Konfigurasikan hosting startup assembly untuk menggunakan Azure SignalR SDK. Edit launchSettings.json dan tambahkan konfigurasi seperti contoh berikut di dalam environmentVariables:

    "environmentVariables": {
        ...,
       "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.Azure.SignalR"
     }
    
    

Mengalami masalah? Beri tahu kami.

Membersihkan sumber daya

Untuk menghapus sumber daya yang dibuat dalam tutorial ini, hapus grup sumber daya menggunakan portal Microsoft Azure.

Sumber daya tambahan

Langkah berikutnya

Dalam tutorial ini, Anda mempelajari cara:

  • Bangun ruang obrolan sederhana dengan templat aplikasi Blazor Server.
  • Bekerja dengan komponen Razor.
  • Gunakan penanganan peristiwa dan pengikatan data pada komponen Razor.
  • Terapkan cepat ke Azure App Service di Visual Studio.
  • Migrasi dari SignalR lokal ke Layanan SignalR Azure.

Baca selengkapnya tentang ketersediaan tinggi: