Bagikan melalui


Menggunakan ASP.NET Core SignalR dengan Blazor

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Peringatan

Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Tutorial ini memberikan pengalaman kerja dasar untuk membangun aplikasi real-time menggunakan SignalR dengan Blazor. Artikel ini berguna bagi pengembang yang sudah terbiasa SignalR dan berusaha memahami cara menggunakan SignalR dalam Blazor aplikasi. Untuk panduan terperinci tentang SignalR kerangka kerja dan Blazor , lihat kumpulan dokumentasi referensi berikut dan dokumentasi API:

Pelajari cara:

  • Membuat Blazor aplikasi
  • SignalR Menambahkan pustaka klien
  • SignalR Menambahkan hub
  • Menambahkan SignalR layanan dan titik akhir untuk SignalR hub
  • Razor Menambahkan kode komponen untuk obrolan

Di akhir tutorial ini, Anda akan memiliki aplikasi obrolan yang berfungsi.

Prasyarat

Visual Studio (rilis terbaru) dengan beban kerja pengembangan ASP.NET dan web

Aplikasi sampel

Mengunduh contoh aplikasi obrolan tutorial tidak diperlukan untuk tutorial ini. Aplikasi sampel adalah aplikasi kerja akhir yang diproduksi dengan mengikuti langkah-langkah tutorial ini. Saat Anda membuka repositori sampel, buka folder versi yang Anda rencanakan untuk ditargetkan dan temukan sampel bernama BlazorSignalRApp.

Mengunduh contoh aplikasi obrolan tutorial tidak diperlukan untuk tutorial ini. Aplikasi sampel adalah aplikasi kerja akhir yang diproduksi dengan mengikuti langkah-langkah tutorial ini. Saat Anda membuka repositori sampel, buka folder versi yang Anda rencanakan untuk ditargetkan dan temukan sampel bernama BlazorWebAssemblySignalRApp.

Melihat atau mengunduh kode sampel (cara mengunduh)

Membuat Blazor Aplikasi Web

Ikuti panduan untuk pilihan alat Anda:

Catatan

Visual Studio 2022 atau yang lebih baru dan .NET Core SDK 8.0.0 atau yang lebih baru diperlukan.

Di Visual Studio:

  • Pilih Buat proyek baru dari Jendela Mulai atau pilih File>Proyek Baru>dari bilah menu.
  • Dalam dialog Buat proyek baru, pilih Blazor Aplikasi Web dari daftar templat proyek. Pilih tombol Berikutnya.
  • Dalam dialog Konfigurasikan proyek baru Anda, beri nama proyek di bidang Nama proyekBlazorSignalRApp, termasuk pencocokan kapitalisasi. Menggunakan nama proyek yang tepat ini penting untuk memastikan bahwa namespace layanan cocok untuk kode yang Anda salin dari tutorial ke dalam aplikasi yang Sedang Anda bangun.
  • Konfirmasikan bahwa Lokasi untuk aplikasi cocok. Biarkan kotak centang Tempatkan solusi dan proyek di direktori yang sama dipilih. Pilih tombol Berikutnya.
  • Dalam dialog Informasi tambahan, gunakan pengaturan berikut ini:
    • Kerangka kerja: Konfirmasikan bahwa kerangka kerja terbaru dipilih. Jika daftar dropdown Kerangka Kerja Visual Studio tidak menyertakan kerangka kerja .NET terbaru yang tersedia, perbarui Visual Studio dan mulai ulang tutorial.
    • Jenis autentikasi: Tidak ada
    • Mengonfigurasi untuk HTTPS: Dipilih
    • Mode render interaktif: WebAssembly
    • Lokasi interaktivitas: Per halaman/komponen
    • Sertakan halaman sampel: Dipilih
    • Jangan gunakan pernyataan tingkat atas: Tidak dipilih
    • Pilih Buat.

Panduan dalam artikel ini menggunakan komponen WebAssembly untuk SignalR klien karena tidak masuk akal untuk digunakan SignalR untuk terhubung ke hub dari komponen Interactive Server di aplikasi yang sama, karena dapat menyebabkan kelelahan port server.

SignalR Menambahkan pustaka klien

Di Penjelajah Solusi, klik BlazorSignalRApp.Client kanan proyek dan pilih Kelola Paket NuGet.

Dalam dialog Kelola Paket NuGet, konfirmasikan bahwa sumber Paket diatur ke nuget.org.

Dengan Telusuri dipilih, ketik Microsoft.AspNetCore.SignalR.Client di kotak pencarian.

Dalam hasil pencarian, pilih rilis Microsoft.AspNetCore.SignalR.Client terbaru paket. Pilih Instal.

Jika dialog Pratinjau Perubahan muncul, pilih OK.

Jika dialog Penerimaan Lisensi muncul, pilih Saya Terima jika Anda setuju dengan persyaratan lisensi.

SignalR Menambahkan hub

Dalam proyek server BlazorSignalRApp , buat Hubs folder (jamak) dan tambahkan kelas berikut ChatHub (Hubs/ChatHub.cs):

using Microsoft.AspNetCore.SignalR;

namespace BlazorSignalRApp.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

Menambahkan layanan dan titik akhir untuk SignalR hub

Program Buka file proyek serverBlazorSignalRApp.

Tambahkan namespace layanan untuk Microsoft.AspNetCore.ResponseCompression dan ChatHub kelas ke bagian atas file:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorSignalRApp.Hubs;

Menambahkan SignalR dan Merespons layanan Middleware Kompresi:

builder.Services.AddSignalR();

builder.Services.AddResponseCompression(opts =>
{
   opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
       ["application/octet-stream"]);
});

Gunakan Middleware Kompresi Respons di bagian atas konfigurasi alur pemrosesan. Tempatkan baris kode berikut segera setelah baris yang membangun aplikasi (var app = builder.Build();):

app.UseResponseCompression();

Tambahkan titik akhir untuk hub segera sebelum baris yang menjalankan aplikasi (app.Run();):

app.MapHub<ChatHub>("/chathub");

Menambahkan Razor kode komponen untuk obrolan

Tambahkan file berikut Pages/Chat.razor ke BlazorSignalRApp.Client proyek:

@page "/chat"
@rendermode InteractiveWebAssembly
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Chat</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
        {
            await hubConnection.SendAsync("SendMessage", userInput, messageInput);
        }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

Tambahkan entri ke NavMenu komponen untuk mencapai halaman obrolan. Di Components/Layout/NavMenu.razor segera setelah <div> blok untuk Weather komponen, tambahkan blok berikut <div> :

<div class="nav-item px-3">
    <NavLink class="nav-link" href="chat">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Chat
    </NavLink>
</div>

Catatan

Nonaktifkan Middleware Kompresi Respons di Development lingkungan saat menggunakan Hot Reload. Untuk informasi selengkapnya, lihat panduan ASP.NET CoreBlazorSignalR.

Menjalankan aplikasi

Ikuti panduan untuk alat Anda:

Dengan proyek server BlazorSignalRApp yang dipilih di Penjelajah Solusi, tekan F5 untuk menjalankan aplikasi dengan penelusuran kesalahan atau Ctrl+F5 (Windows)/⌘+F5 (macOS) untuk menjalankan aplikasi tanpa penelusuran kesalahan.

Salin URL dari bilah alamat, buka instans atau tab browser lain, dan tempelkan URL di bilah alamat.

Pilih salah satu browser, masukkan nama dan pesan, dan pilih tombol untuk mengirim pesan. Nama dan pesan ditampilkan di kedua halaman secara instan:

SignalRBlazor aplikasi sampel terbuka di dua jendela browser yang menampilkan pesan yang ditukar.

Kutipan: Star Trek VI: The Undiscovered Country ©1991 Paramount

Pengalaman yang dihosting Blazor WebAssembly

Membuat aplikasi

Ikuti panduan untuk pilihan alat Anda untuk membuat aplikasi yang dihosting Blazor WebAssembly :

Catatan

Visual Studio 2022 atau yang lebih baru dan .NET Core SDK 6.0.0 atau yang lebih baru diperlukan.

Buat proyek baru.

Blazor WebAssembly Pilih templat Aplikasi. Pilih Selanjutnya.

Ketik BlazorWebAssemblySignalRApp di bidang Nama proyek. Konfirmasikan entri Lokasi sudah benar atau sediakan lokasi untuk proyek. Pilih Selanjutnya.

Dalam dialog Informasi tambahan, pilih kotak centang ASP.NET Core Hosted.

Pilih Buat.

Konfirmasikan bahwa aplikasi yang dihosting Blazor WebAssembly dibuat: Di Penjelajah Solusi, konfirmasikan keberadaan Client proyek dan Server proyek. Jika kedua proyek tidak ada, mulai lagi dan konfirmasi pilihan kotak centang ASP.NET Core Hosted sebelum memilih Buat.

SignalR Menambahkan pustaka klien

Di Penjelajah Solusi, klik BlazorWebAssemblySignalRApp.Client kanan proyek dan pilih Kelola Paket NuGet.

Dalam dialog Kelola Paket NuGet, konfirmasikan bahwa sumber Paket diatur ke nuget.org.

Dengan Telusuri dipilih, ketik Microsoft.AspNetCore.SignalR.Client di kotak pencarian.

Di hasil pencarian, pilih Microsoft.AspNetCore.SignalR.Client paket. Atur versi agar sesuai dengan kerangka kerja bersama aplikasi. Pilih Instal.

Jika dialog Pratinjau Perubahan muncul, pilih OK.

Jika dialog Penerimaan Lisensi muncul, pilih Saya Terima jika Anda setuju dengan persyaratan lisensi.

SignalR Menambahkan hub

BlazorWebAssemblySignalRApp.Server Dalam proyek, buat Hubs folder (jamak) dan tambahkan kelas berikut ChatHub (Hubs/ChatHub.cs):

using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Menambahkan layanan dan titik akhir untuk SignalR hub

BlazorWebAssemblySignalRApp.Server Dalam proyek, buka Program.cs file .

Tambahkan namespace untuk ChatHub kelas ke bagian atas file:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Menambahkan SignalR dan Merespons layanan Middleware Kompresi:

builder.Services.AddSignalR();
builder.Services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Gunakan Middleware Kompresi Respons di bagian atas konfigurasi alur pemrosesan segera setelah baris yang membangun aplikasi:

app.UseResponseCompression();

Antara titik akhir untuk pengontrol dan fallback sisi klien, tambahkan titik akhir untuk hub. Segera setelah baris app.MapControllers();, tambahkan baris berikut:

app.MapHub<ChatHub>("/chathub");

BlazorWebAssemblySignalRApp.Server Dalam proyek, buka Startup.cs file .

Tambahkan namespace untuk ChatHub kelas ke bagian atas file:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Menambahkan SignalR dan Merespons layanan Middleware Kompresi:

services.AddSignalR();
services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Gunakan Middleware Kompresi Respons di bagian atas konfigurasi alur pemrosesan:

app.UseResponseCompression();

Antara titik akhir untuk pengontrol dan fallback sisi klien, tambahkan titik akhir untuk hub segera setelah baris endpoints.MapControllers();:

endpoints.MapHub<ChatHub>("/chathub");

Menambahkan Razor kode komponen untuk obrolan

BlazorWebAssemblySignalRApp.Client Dalam proyek, buka Pages/Index.razor file .

Ganti markup dengan kode berikut:

@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IAsyncDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public void Dispose()
    {
        _ = hubConnection?.DisposeAsync();
    }
}

Catatan

Nonaktifkan Middleware Kompresi Respons di Development lingkungan saat menggunakan Hot Reload. Untuk informasi selengkapnya, lihat panduan ASP.NET CoreBlazorSignalR.

Menjalankan aplikasi

Ikuti panduan untuk alat Anda:

Di Penjelajah Solusi, pilih BlazorWebAssemblySignalRApp.Server proyek. Tekan F5 untuk menjalankan aplikasi dengan penelusuran kesalahan atau Ctrl+F5 (Windows)/⌘+F5 (macOS) untuk menjalankan aplikasi tanpa penelusuran kesalahan.

Penting

Saat menjalankan aplikasi yang dihosting, jalankan Blazor WebAssembly aplikasi dari proyek solusiServer .

Google Chrome atau Microsoft Edge harus menjadi browser yang dipilih untuk sesi penelusuran kesalahan.

Jika aplikasi gagal dimulai di browser:

  • Di konsol .NET, konfirmasikan bahwa solusi berjalan dari proyek ""Server.
  • Refresh browser menggunakan tombol muat ulang browser.

Salin URL dari bilah alamat, buka instans atau tab browser lain, dan tempelkan URL di bilah alamat.

Pilih salah satu browser, masukkan nama dan pesan, dan pilih tombol untuk mengirim pesan. Nama dan pesan ditampilkan di kedua halaman secara instan:

SignalRBlazor aplikasi sampel terbuka di dua jendela browser yang menampilkan pesan yang ditukar.

Kutipan: Star Trek VI: The Undiscovered Country ©1991 Paramount

Langkah berikutnya

Dalam tutorial ini, Anda mempelajari cara:

  • Membuat Blazor aplikasi
  • SignalR Menambahkan pustaka klien
  • SignalR Menambahkan hub
  • Menambahkan SignalR layanan dan titik akhir untuk SignalR hub
  • Razor Menambahkan kode komponen untuk obrolan

Untuk panduan terperinci tentang SignalR kerangka kerja dan Blazor , lihat kumpulan dokumentasi referensi berikut:

Sumber Daya Tambahan: