ASP.NET Core SignalR .NET Client
Pustaka klien ASP.NET Core SignalR .NET memungkinkan Anda berkomunikasi dengan SignalR hub dari aplikasi .NET.
Melihat atau mengunduh kode sampel (cara mengunduh)
Sampel kode dalam artikel ini adalah aplikasi WPF yang menggunakan klien ASP.NET Core SignalR .NET.
SignalR Menginstal paket klien .NET
Microsoft.AspNetCore.SignalR. Paket klien diperlukan agar klien .NET tersambung ke SignalR hub.
Untuk menginstal pustaka klien, jalankan perintah berikut di jendela Konsol Manajer Paket:
Install-Package Microsoft.AspNetCore.SignalR.Client
Menyambungkan ke hub
Untuk membuat koneksi, buat HubConnectionBuilder
dan panggil Build
. URL hub, protokol, jenis transportasi, tingkat log, header, dan opsi lainnya dapat dikonfigurasi saat membangun koneksi. Konfigurasikan opsi yang diperlukan dengan memasukkan salah satu metode ke HubConnectionBuilder
dalam Build
. Mulai koneksi dengan StartAsync
.
using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.AspNetCore.SignalR.Client;
namespace SignalRChatClient
{
public partial class MainWindow : Window
{
HubConnection connection;
public MainWindow()
{
InitializeComponent();
connection = new HubConnectionBuilder()
.WithUrl("http://localhost:53353/ChatHub")
.Build();
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
}
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
try
{
await connection.StartAsync();
messagesList.Items.Add("Connection started");
connectButton.IsEnabled = false;
sendButton.IsEnabled = true;
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
private async void sendButton_Click(object sender, RoutedEventArgs e)
{
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
}
}
Menangani koneksi yang hilang
Menyambungkan ulang secara otomatis
HubConnection dapat dikonfigurasi untuk terhubung kembali secara otomatis menggunakan WithAutomaticReconnect
metode pada HubConnectionBuilder. Ini tidak akan secara otomatis terhubung kembali secara default.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect()
.Build();
Tanpa parameter apa pun, WithAutomaticReconnect()
mengonfigurasi klien untuk menunggu masing-masing 0, 2, 10, dan 30 detik sebelum mencoba setiap upaya koneksi ulang, berhenti setelah empat upaya yang gagal.
Sebelum memulai upaya koneksi ulang, HubConnection
akan beralih ke HubConnectionState.Reconnecting
status dan mengaktifkan Reconnecting
peristiwa. Ini memberikan kesempatan untuk memperingatkan pengguna bahwa koneksi telah hilang dan untuk menonaktifkan elemen UI. Aplikasi non-interaktif dapat mulai mengantre atau menghilangkan pesan.
connection.Reconnecting += error =>
{
Debug.Assert(connection.State == HubConnectionState.Reconnecting);
// Notify users the connection was lost and the client is reconnecting.
// Start queuing or dropping messages.
return Task.CompletedTask;
};
Jika klien berhasil terhubung kembali dalam empat upaya pertamanya, HubConnection
akan transisi kembali ke Connected
status dan menembakkan Reconnected
peristiwa. Ini memberikan kesempatan untuk memberi tahu pengguna bahwa koneksi telah dipublikasikan kembali dan menghapus antrean pesan yang diantrekan.
Karena koneksi terlihat sama sekali baru ke server, baru ConnectionId
akan disediakan untuk penanganan Reconnected
aktivitas.
Peringatan
Parameter Reconnected
penanganan connectionId
aktivitas akan null jika HubConnection
dikonfigurasi untuk melewati negosiasi.
connection.Reconnected += connectionId =>
{
Debug.Assert(connection.State == HubConnectionState.Connected);
// Notify users the connection was reestablished.
// Start dequeuing messages queued while reconnecting if any.
return Task.CompletedTask;
};
WithAutomaticReconnect()
tidak akan mengonfigurasi HubConnection
untuk mencoba kembali kegagalan awal, jadi kegagalan mulai perlu ditangani secara manual:
public static async Task<bool> ConnectWithRetryAsync(HubConnection connection, CancellationToken token)
{
// Keep trying to until we can start or the token is canceled.
while (true)
{
try
{
await connection.StartAsync(token);
Debug.Assert(connection.State == HubConnectionState.Connected);
return true;
}
catch when (token.IsCancellationRequested)
{
return false;
}
catch
{
// Failed to connect, trying again in 5000 ms.
Debug.Assert(connection.State == HubConnectionState.Disconnected);
await Task.Delay(5000);
}
}
}
Jika klien tidak berhasil menyambungkan kembali dalam empat upaya pertamanya, HubConnection
akan beralih ke Disconnected
status dan mengaktifkan Closed peristiwa. Ini memberikan kesempatan untuk mencoba memulai ulang koneksi secara manual atau memberi tahu pengguna bahwa koneksi telah hilang secara permanen.
connection.Closed += error =>
{
Debug.Assert(connection.State == HubConnectionState.Disconnected);
// Notify users the connection has been closed or manually try to restart the connection.
return Task.CompletedTask;
};
Untuk mengonfigurasi jumlah kustom upaya koneksi ulang sebelum memutuskan atau mengubah waktu koneksi ulang, WithAutomaticReconnect
menerima array angka yang mewakili penundaan dalam milidetik untuk menunggu sebelum memulai setiap upaya koneksi ulang.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
.Build();
// .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) yields the default behavior.
Contoh sebelumnya mengonfigurasi HubConnection
untuk mulai mencoba menyambungkan kembali segera setelah koneksi hilang. Ini juga berlaku untuk konfigurasi default.
Jika upaya koneksi ulang pertama gagal, upaya koneksi ulang kedua juga akan segera dimulai alih-alih menunggu 2 detik seperti dalam konfigurasi default.
Jika upaya koneksi ulang kedua gagal, upaya koneksi ulang ketiga akan dimulai dalam 10 detik yang lagi seperti konfigurasi default.
Perilaku kustom kemudian beralih lagi dari perilaku default dengan berhenti setelah kegagalan upaya koneksi ulang ketiga. Dalam konfigurasi default akan ada satu lagi upaya sambungkan kembali dalam 30 detik lagi.
Jika Anda ingin kontrol yang lebih besar atas waktu dan jumlah upaya koneksi ulang otomatis, WithAutomaticReconnect
menerima objek yang mengimplementasikan IRetryPolicy
antarmuka, yang memiliki satu metode bernama NextRetryDelay
.
NextRetryDelay
mengambil satu argumen dengan jenis RetryContext
. memiliki RetryContext
tiga properti: PreviousRetryCount
, ElapsedTime
dan RetryReason
, yang masing-masing adalah long
, a TimeSpan
dan Exception
. Sebelum upaya koneksi ulang pertama, dan PreviousRetryCount
ElapsedTime
akan menjadi nol, dan RetryReason
akan menjadi Pengecualian yang menyebabkan koneksi hilang. Setelah setiap upaya coba lagi yang gagal, PreviousRetryCount
akan bertambah satu, ElapsedTime
akan diperbarui untuk mencerminkan jumlah waktu yang dihabiskan untuk menyambungkan kembali sejauh ini, dan RetryReason
akan menjadi Pengecualian yang menyebabkan upaya koneksi ulang terakhir gagal.
NextRetryDelay
harus mengembalikan TimeSpan yang mewakili waktu untuk menunggu sebelum upaya koneksi ulang berikutnya atau null
jika HubConnection
harus berhenti menyambungkan kembali.
public class RandomRetryPolicy : IRetryPolicy
{
private readonly Random _random = new Random();
public TimeSpan? NextRetryDelay(RetryContext retryContext)
{
// If we've been reconnecting for less than 60 seconds so far,
// wait between 0 and 10 seconds before the next reconnect attempt.
if (retryContext.ElapsedTime < TimeSpan.FromSeconds(60))
{
return TimeSpan.FromSeconds(_random.NextDouble() * 10);
}
else
{
// If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
return null;
}
}
}
HubConnection connection = new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new RandomRetryPolicy())
.Build();
Atau, Anda dapat menulis kode yang akan menghubungkan kembali klien Anda secara manual seperti yang ditunjukkan dalam Sambungkan kembali secara manual.
Menyambungkan ulang secara manual
Peringatan
Sebelum 3.0, klien .NET untuk SignalR tidak terhubung kembali secara otomatis. Anda harus menulis kode yang akan menghubungkan kembali klien Anda secara manual.
Closed Gunakan peristiwa untuk merespons koneksi yang hilang. Misalnya, Anda mungkin ingin mengotomatiskan koneksi ulang.
Kejadian ini Closed
memerlukan delegasi yang mengembalikan Task
, yang memungkinkan kode asinkron berjalan tanpa menggunakan async void
. Untuk memenuhi tanda tangan delegasi dalam Closed
penanganan aktivitas yang berjalan secara sinkron, kembalikan Task.CompletedTask
:
connection.Closed += (error) => {
// Do your close logic.
return Task.CompletedTask;
};
Alasan utama dukungan asinkron adalah agar Anda dapat memulai ulang koneksi. Memulai koneksi adalah tindakan asinkron.
Closed
Dalam handler yang memulai ulang koneksi, pertimbangkan untuk menunggu beberapa penundaan acak untuk mencegah kelebihan beban server, seperti yang ditunjukkan dalam contoh berikut:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
Metode hub panggilan dari klien
InvokeAsync
memanggil metode di hub. Teruskan nama metode hub dan argumen apa pun yang ditentukan dalam metode hub ke InvokeAsync
. SignalR asinkron, jadi gunakan async
dan await
saat melakukan panggilan.
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
Metode InvokeAsync
mengembalikan yang Task
selesai ketika metode server kembali. Nilai pengembalian, jika ada, disediakan sebagai hasil dari Task
. Setiap pengecualian yang dilemparkan oleh metode di server menghasilkan kesalahan Task
. Gunakan await
sintaks untuk menunggu metode server selesai dan try...catch
sintaks untuk menangani kesalahan.
Metode SendAsync
mengembalikan yang Task
selesai ketika pesan telah dikirim ke server. Tidak ada nilai pengembalian yang disediakan karena ini Task
tidak menunggu sampai metode server selesai. Setiap pengecualian yang dilemparkan pada klien saat mengirim pesan menghasilkan kesalahan Task
. Gunakan await
dan try...catch
sintaks untuk menangani kesalahan pengiriman.
Catatan
Metode hub panggilan dari klien hanya didukung saat menggunakan Layanan Azure SignalR dalam mode Default . Untuk informasi selengkapnya, lihat Tanya Jawab Umum (azure-signalr repositori GitHub).
Memanggil metode klien dari hub
Tentukan metode yang digunakan connection.On
hub setelah membangun, tetapi sebelum memulai koneksi.
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
Kode sebelumnya dalam connection.On
berjalan ketika kode sisi server memanggilnya menggunakan SendAsync
metode .
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user,message);
}
Catatan
Meskipun sisi hub koneksi mendukung olahpesan yang ditik dengan kuat, klien harus mendaftar menggunakan metode HubConnection.On generik dengan nama metode . Misalnya, lihat Host ASP.NET Core SignalR di layanan latar belakang.
Penanganan kesalahan dan pengelogan
Menangani kesalahan dengan pernyataan try-catch. Exception
Periksa objek untuk menentukan tindakan yang tepat untuk diambil setelah terjadi kesalahan.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
Sumber Daya Tambahan:
ASP.NET Core