Menggunakan hub untuk SignalR ASP.NET Core
Oleh Rachel Appel dan Kevin Griffin
SignalR Hubs API memungkinkan klien yang terhubung untuk memanggil metode di server. Server mendefinisikan metode yang dipanggil dari klien dan klien menentukan metode yang dipanggil dari server. SignalR mengurus semua yang diperlukan untuk memungkinkan komunikasi klien-ke-server dan server-ke-klien secara real-time.
Mengonfigurasi SignalR hub
Untuk mendaftarkan layanan yang diperlukan oleh SignalR hub, hubungi AddSignalR di Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
Untuk mengonfigurasi SignalR titik akhir, panggil MapHub, juga di Program.cs:
app.MapRazorPages();
app.MapHub<ChatHub>("/Chat");
app.Run();
Membuat dan menggunakan hub
Buat hub dengan mendeklarasikan kelas yang mewarisi dari Hub. Tambahkan public metode ke kelas untuk membuatnya dapat dipanggil dari klien:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Catatan
Hub bersifat sementara:
- Jangan menyimpan status di properti kelas hub. Setiap panggilan metode hub dijalankan pada instans hub baru.
- Gunakan
awaitsaat memanggil metode asinkron yang bergantung pada hub tetap hidup. Misalnya, metode sepertiClients.All.SendAsync(...)dapat gagal jika dipanggil tanpaawaitdan metode hub selesai sebelumSendAsyncselesai.
Objek Konteks
Kelas Hub menyertakan Context properti yang berisi properti berikut dengan informasi tentang koneksi:
| Properti | Deskripsi |
|---|---|
| ConnectionId | Mendapatkan ID unik untuk koneksi, yang ditetapkan oleh SignalR. Ada satu ID koneksi untuk setiap koneksi. |
| UserIdentifier | Mendapatkan pengidentifikasi pengguna. Secara default, SignalR menggunakan ClaimTypes.NameIdentifier dari yang ClaimsPrincipal terkait dengan koneksi sebagai pengidentifikasi pengguna. |
| User | Mendapatkan yang ClaimsPrincipal terkait dengan pengguna saat ini. |
| Items | Mendapatkan kumpulan kunci/nilai yang dapat digunakan untuk berbagi data dalam cakupan koneksi ini. Data dapat disimpan dalam koleksi ini dan akan bertahan untuk koneksi di berbagai pemanggilan metode hub. |
| Features | Mendapatkan koleksi fitur yang tersedia pada koneksi. Untuk saat ini, koleksi ini tidak diperlukan dalam sebagian besar skenario, sehingga belum didokumenkan secara rinci. |
| ConnectionAborted | CancellationToken Mendapatkan yang memberi tahu ketika koneksi dibatalkan. |
Hub.Context juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| GetHttpContext | Mengembalikan HttpContext untuk koneksi, atau null jika koneksi tidak terkait dengan permintaan HTTP. Untuk koneksi HTTP, gunakan metode ini untuk mendapatkan informasi seperti header HTTP dan string kueri. |
| Abort | Membatalkan koneksi. |
Objek Klien
Kelas Hub menyertakan Clients properti yang berisi properti berikut untuk komunikasi antara server dan klien:
| Properti | Deskripsi |
|---|---|
| All | Memanggil metode pada semua klien yang terhubung |
| Caller | Memanggil metode pada klien yang memanggil metode hub |
| Others | Memanggil metode pada semua klien yang terhubung kecuali klien yang memanggil metode |
Hub.Clients juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| AllExcept | Memanggil metode pada semua klien yang terhubung kecuali untuk koneksi yang ditentukan |
| Client | Memanggil metode pada klien tertentu yang terhubung |
| Clients | Memanggil metode pada klien tertentu yang terhubung |
| Group | Memanggil metode pada semua koneksi dalam grup yang ditentukan |
| GroupExcept | Memanggil metode pada semua koneksi dalam grup yang ditentukan, kecuali koneksi yang ditentukan |
| Groups | Memanggil metode pada beberapa grup koneksi |
| OthersInGroup | Memanggil metode pada sekelompok koneksi, tidak termasuk klien yang memanggil metode hub |
| User | Memanggil metode pada semua koneksi yang terkait dengan pengguna tertentu |
| Users | Memanggil metode pada semua koneksi yang terkait dengan pengguna yang ditentukan |
Setiap properti atau metode dalam tabel sebelumnya mengembalikan objek dengan SendAsync metode . Metode ini SendAsync menerima nama metode klien untuk dipanggil dan parameter apa pun.
Mengirim pesan ke klien
Untuk melakukan panggilan ke klien tertentu, gunakan properti Clients objek . Dalam contoh berikut, ada tiga metode hub:
SendMessagemengirim pesan ke semua klien yang terhubung, menggunakanClients.All.SendMessageToCallermengirim pesan kembali ke pemanggil, menggunakanClients.Caller.SendMessageToGroupmengirim pesan ke semua klien dalamSignalR Usersgrup.
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
Hub yang sangat ditik
Kelemahan penggunaan SendAsync adalah bergantung pada string untuk menentukan metode klien yang akan dipanggil. Ini membuat kode terbuka untuk kesalahan runtime jika nama metode salah eja atau hilang dari klien.
Alternatif untuk menggunakan SendAsync adalah dengan mengetik Hub kelas dengan kuat .Hub<T> Dalam contoh berikut, ChatHub metode klien telah diekstrak keluar ke antarmuka yang disebut IChatClient:
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Antarmuka ini dapat digunakan untuk merefaktor contoh sebelumnya ChatHub untuk diketik dengan kuat:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
=> await Clients.All.ReceiveMessage(user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.ReceiveMessage(user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").ReceiveMessage(user, message);
}
Menggunakan Hub<IChatClient> memungkinkan pemeriksaan waktu kompilasi metode klien. Ini mencegah masalah yang disebabkan oleh penggunaan string, karena Hub<T> hanya dapat menyediakan akses ke metode yang ditentukan dalam antarmuka. Menggunakan jenis yang sangat Hub<T> menonaktifkan kemampuan untuk menggunakan SendAsync.
Catatan
Akhiran Async tidak dilucuti dari nama metode. Kecuali metode klien didefinisikan dengan .on('MyMethodAsync'), jangan gunakan MyMethodAsync sebagai nama.
Mengubah nama metode hub
Secara default, nama metode hub server adalah nama metode .NET. Untuk mengubah perilaku default ini untuk metode tertentu, gunakan atribut HubMethodName . Klien harus menggunakan nama ini alih-alih nama metode .NET saat memanggil metode :
[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
=> await Clients.User(user).SendAsync("ReceiveMessage", user, message);
Menangani peristiwa untuk koneksi
SignalR Hubs API menyediakan OnConnectedAsync metode virtual dan OnDisconnectedAsync untuk mengelola dan melacak koneksi. Ambil alih OnConnectedAsync metode virtual untuk melakukan tindakan saat klien terhubung ke hub, seperti menambahkannya ke grup:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
Ambil alih OnDisconnectedAsync metode virtual untuk melakukan tindakan saat klien terputus. Jika klien memutuskan sambungan dengan sengaja, seperti dengan memanggil connection.stop(), exception parameter diatur ke null. Namun, jika klien terputus karena kesalahan, seperti kegagalan jaringan, exception parameter berisi pengecualian yang menjelaskan kegagalan:
public override async Task OnDisconnectedAsync(Exception? exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
Menangani kesalahan
Pengecualian yang dilemparkan dalam metode hub dikirim ke klien yang memanggil metode . Pada klien JavaScript, invoke metode mengembalikan JavaScript Promise. Klien dapat melampirkan catch handler ke janji yang dikembalikan atau digunakan trycatch/dengan async/await untuk menangani pengecualian:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Koneksi tidak ditutup saat hub melemparkan pengecualian. Secara default, SignalR mengembalikan pesan kesalahan generik ke klien, seperti yang ditunjukkan dalam contoh berikut:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'SendMessage' on the server.
Pengecualian tak terduga sering berisi informasi sensitif, seperti nama server database dalam pengecualian yang dipicu ketika koneksi database gagal. SignalR tidak mengekspos pesan kesalahan terperinci ini secara default sebagai langkah keamanan. Untuk informasi selengkapnya tentang mengapa detail pengecualian ditekan, lihat Pertimbangan keamanan di ASP.NET Core SignalR.
Jika kondisi luar biasa harus disebarluaskan ke klien, gunakan HubException kelas . HubException Jika dilemparkan dalam metode hub, SignalRmengirim seluruh pesan pengecualian ke klien, tidak dimodifikasi:
public Task ThrowException()
=> throw new HubException("This error will be sent to the client!");
Catatan
SignalR hanya mengirim Message properti pengecualian ke klien. Jejak tumpukan dan properti lain pada pengecualian tidak tersedia untuk klien.
Sumber Daya Tambahan:
Oleh Rachel Appel dan Kevin Griffin
Melihat atau mengunduh kode sampel(cara mengunduh)
Apa itu SignalR hub
SignalR Hubs API memungkinkan Anda memanggil metode pada klien yang terhubung dari server. Dalam kode server, Anda menentukan metode yang dipanggil oleh klien. Dalam kode klien, Anda menentukan metode yang dipanggil dari server. SignalR mengurus segala sesuatu di belakang layar yang memungkinkan komunikasi klien-ke-server dan server-ke-klien real-time.
Mengonfigurasi SignalR hub
Middleware SignalR memerlukan beberapa layanan, yang dikonfigurasi dengan memanggil AddSignalR:
services.AddSignalR();
Saat menambahkan SignalR fungsionalitas ke aplikasi ASP.NET Core, siapkan SignalR rute dengan memanggil MapHub panggilan Startup.Configure balik metode UseEndpoints :
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
});
Membuat dan menggunakan hub
Buat hub dengan mendeklarasikan kelas yang mewarisi dari Hub, dan menambahkan metode publik ke dalamnya. Klien dapat memanggil metode yang didefinisikan sebagai public:
public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Anda dapat menentukan jenis pengembalian dan parameter, termasuk jenis dan array kompleks, seperti yang Anda lakukan dalam metode C# apa pun. SignalR menangani serialisasi dan deserialisasi objek dan array kompleks dalam parameter Anda dan mengembalikan nilai.
Catatan
Hub bersifat sementara:
- Jangan menyimpan status dalam properti di kelas hub. Setiap panggilan metode hub dijalankan pada instans hub baru.
- Gunakan
awaitsaat memanggil metode asinkron yang bergantung pada hub yang tetap hidup. Misalnya, metode sepertiClients.All.SendAsync(...)dapat gagal jika dipanggil tanpaawaitdan metode hub selesai sebelumSendAsyncselesai.
Objek Konteks
Kelas Hub memiliki Context properti yang berisi properti berikut dengan informasi tentang koneksi:
| Properti | Deskripsi |
|---|---|
| ConnectionId | Mendapatkan ID unik untuk koneksi, yang ditetapkan oleh SignalR. Ada satu ID koneksi untuk setiap koneksi. |
| UserIdentifier | Mendapatkan pengidentifikasi pengguna. Secara default, SignalR menggunakan ClaimTypes.NameIdentifier dari yang ClaimsPrincipal terkait dengan koneksi sebagai pengidentifikasi pengguna. |
| User | Mendapatkan yang ClaimsPrincipal terkait dengan pengguna saat ini. |
| Items | Mendapatkan kumpulan kunci/nilai yang dapat digunakan untuk berbagi data dalam cakupan koneksi ini. Data dapat disimpan dalam koleksi ini dan akan bertahan untuk koneksi di berbagai pemanggilan metode hub. |
| Features | Mendapatkan koleksi fitur yang tersedia pada koneksi. Untuk saat ini, koleksi ini tidak diperlukan dalam sebagian besar skenario, sehingga belum didokumenkan secara rinci. |
| ConnectionAborted | CancellationToken Mendapatkan yang memberi tahu ketika koneksi dibatalkan. |
Hub.Context juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| GetHttpContext | Mengembalikan HttpContext untuk koneksi, atau null jika koneksi tidak terkait dengan permintaan HTTP. Untuk koneksi HTTP, Anda dapat menggunakan metode ini untuk mendapatkan informasi seperti header HTTP dan string kueri. |
| Abort | Membatalkan koneksi. |
Objek Klien
Kelas Hub memiliki Clients properti yang berisi properti berikut untuk komunikasi antara server dan klien:
| Properti | Deskripsi |
|---|---|
| All | Memanggil metode pada semua klien yang terhubung |
| Caller | Memanggil metode pada klien yang memanggil metode hub |
| Others | Memanggil metode pada semua klien yang terhubung kecuali klien yang memanggil metode |
Hub.Clients juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| AllExcept | Memanggil metode pada semua klien yang terhubung kecuali untuk koneksi yang ditentukan |
| Client | Memanggil metode pada klien tertentu yang terhubung |
| Clients | Memanggil metode pada klien tertentu yang terhubung |
| Group | Memanggil metode pada semua koneksi dalam grup yang ditentukan |
| GroupExcept | Memanggil metode pada semua koneksi dalam grup yang ditentukan, kecuali koneksi yang ditentukan |
| Groups | Memanggil metode pada beberapa grup koneksi |
| OthersInGroup | Memanggil metode pada sekelompok koneksi, tidak termasuk klien yang memanggil metode hub |
| User | Memanggil metode pada semua koneksi yang terkait dengan pengguna tertentu |
| Users | Memanggil metode pada semua koneksi yang terkait dengan pengguna yang ditentukan |
Setiap properti atau metode dalam tabel sebelumnya mengembalikan objek dengan SendAsync metode . Metode ini SendAsync memungkinkan Anda untuk memberikan nama dan parameter metode klien untuk dipanggil.
Mengirim pesan ke klien
Untuk melakukan panggilan ke klien tertentu, gunakan properti Clients objek . Dalam contoh berikut, ada tiga metode Hub:
SendMessagemengirim pesan ke semua klien yang terhubung, menggunakanClients.All.SendMessageToCallermengirim pesan kembali ke pemanggil, menggunakanClients.Caller.SendMessageToGroupmengirim pesan ke semua klien dalamSignalR Usersgrup.
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string user, string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}
Hub yang sangat ditik
Kelemahan penggunaan SendAsync adalah mengandalkan string ajaib untuk menentukan metode klien yang akan dipanggil. Ini membuat kode terbuka untuk kesalahan runtime jika nama metode salah eja atau hilang dari klien.
Alternatif untuk menggunakan SendAsync adalah mengetik Hub dengan kuat dengan Hub<T>. Dalam contoh berikut, ChatHub metode klien telah diekstraksi ke antarmuka yang disebut IChatClient.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Antarmuka ini dapat digunakan untuk merefaktor contoh sebelumnya ChatHub :
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.ReceiveMessage(user, message);
}
}
Menggunakan Hub<IChatClient> memungkinkan pemeriksaan waktu kompilasi metode klien. Ini mencegah masalah yang disebabkan oleh penggunaan string ajaib, karena Hub<T> hanya dapat menyediakan akses ke metode yang ditentukan dalam antarmuka.
Menggunakan jenis yang sangat Hub<T> menonaktifkan kemampuan untuk menggunakan SendAsync. Metode apa pun yang ditentukan pada antarmuka masih dapat didefinisikan sebagai asinkron. Bahkan, masing-masing metode ini harus mengembalikan Task. Karena ini adalah antarmuka, jangan gunakan async kata kunci . Contohnya:
public interface IClient
{
Task ClientMethod();
}
Catatan
Akhiran Async tidak dilucuti dari nama metode. Kecuali metode klien Anda didefinisikan dengan .on('MyMethodAsync'), Anda tidak boleh menggunakan MyMethodAsync sebagai nama.
Mengubah nama metode hub
Secara default, nama metode hub server adalah nama metode .NET. Namun, Anda dapat menggunakan atribut HubMethodName untuk mengubah default ini dan secara manual menentukan nama untuk metode tersebut. Klien harus menggunakan nama ini, alih-alih nama metode .NET, saat memanggil metode :
[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}
Menangani peristiwa untuk koneksi
SignalR Hubs API menyediakan OnConnectedAsync metode virtual dan OnDisconnectedAsync untuk mengelola dan melacak koneksi. Ambil alih OnConnectedAsync metode virtual untuk melakukan tindakan saat klien terhubung ke Hub, seperti menambahkannya ke grup:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
Ambil alih OnDisconnectedAsync metode virtual untuk melakukan tindakan saat klien terputus. Jika klien memutuskan sambungan dengan sengaja (dengan memanggil connection.stop(), misalnya), exception parameternya adalah null. Namun, jika klien terputus karena kesalahan (seperti kegagalan jaringan), exception parameter akan berisi pengecualian yang menjelaskan kegagalan:
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
Peringatan
Peringatan keamanan: Mengekspos ConnectionId dapat menyebabkan peniruan berbahaya jika SignalR server atau versi klien ASP.NET Core 2.2 atau yang lebih lama.
Menangani kesalahan
Pengecualian yang dilemparkan dalam metode hub Anda dikirim ke klien yang memanggil metode . Pada klien JavaScript, invoke metode mengembalikan JavaScript Promise. Ketika klien menerima kesalahan dengan handler yang melekat pada janji menggunakan catch, klien dipanggil dan diteruskan sebagai objek JavaScript Error :
connection.invoke("SendMessage", user, message).catch(err => console.error(err));
Jika Hub Anda memberikan pengecualian, koneksi tidak akan ditutup. Secara default, SignalR mengembalikan pesan kesalahan generik ke klien. Contohnya:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.
Pengecualian tak terduga sering berisi informasi sensitif, seperti nama server database dalam pengecualian yang dipicu saat koneksi database gagal. SignalR tidak mengekspos pesan kesalahan terperinci ini secara default sebagai langkah keamanan. Untuk informasi selengkapnya tentang mengapa detail pengecualian ditekan, lihat Pertimbangan keamanan di ASP.NET Core SignalR.
Jika Anda memiliki kondisi luar biasa yang ingin Anda sebarkan ke klien, Anda dapat menggunakan HubException kelas . Jika Anda melempar HubException dari metode hub Anda, SignalRakan mengirim seluruh pesan ke klien, tidak dimodifikasi:
public Task ThrowException()
{
throw new HubException("This error will be sent to the client!");
}
Catatan
SignalR hanya mengirim Message properti pengecualian ke klien. Jejak tumpukan dan properti lain pada pengecualian tidak tersedia untuk klien.
Sumber Daya Tambahan:
Oleh Rachel Appel dan Kevin Griffin
Melihat atau mengunduh kode sampel(cara mengunduh)
Apa itu SignalR hub
SignalR Hubs API memungkinkan Anda memanggil metode pada klien yang terhubung dari server. Dalam kode server, Anda menentukan metode yang dipanggil oleh klien. Dalam kode klien, Anda menentukan metode yang dipanggil dari server. SignalR mengurus segala sesuatu di belakang layar yang memungkinkan komunikasi klien-ke-server dan server-ke-klien real-time.
Mengonfigurasi SignalR hub
Middleware SignalR memerlukan beberapa layanan, yang dikonfigurasi dengan memanggil AddSignalR:
services.AddSignalR();
Saat menambahkan SignalR fungsionalitas ke aplikasi ASP.NET Core, siapkan SignalR rute dengan memanggil UseSignalR dalam Startup.Configure metode :
app.UseSignalR(route =>
{
route.MapHub<ChatHub>("/chathub");
});
Membuat dan menggunakan hub
Buat hub dengan mendeklarasikan kelas yang mewarisi dari Hub, dan menambahkan metode publik ke dalamnya. Klien dapat memanggil metode yang didefinisikan sebagai public:
public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Anda dapat menentukan jenis pengembalian dan parameter, termasuk jenis dan array kompleks, seperti yang Anda lakukan dalam metode C# apa pun. SignalR menangani serialisasi dan deserialisasi objek dan array kompleks dalam parameter Anda dan mengembalikan nilai.
Catatan
Hub bersifat sementara:
- Jangan menyimpan status dalam properti di kelas hub. Setiap panggilan metode hub dijalankan pada instans hub baru.
- Gunakan
awaitsaat memanggil metode asinkron yang bergantung pada hub yang tetap hidup. Misalnya, metode sepertiClients.All.SendAsync(...)dapat gagal jika dipanggil tanpaawaitdan metode hub selesai sebelumSendAsyncselesai.
Objek Konteks
Kelas Hub memiliki Context properti yang berisi properti berikut dengan informasi tentang koneksi:
| Properti | Deskripsi |
|---|---|
| ConnectionId | Mendapatkan ID unik untuk koneksi, yang ditetapkan oleh SignalR. Ada satu ID koneksi untuk setiap koneksi. |
| UserIdentifier | Mendapatkan pengidentifikasi pengguna. Secara default, SignalR menggunakan ClaimTypes.NameIdentifier dari yang ClaimsPrincipal terkait dengan koneksi sebagai pengidentifikasi pengguna. |
| User | Mendapatkan yang ClaimsPrincipal terkait dengan pengguna saat ini. |
| Items | Mendapatkan kumpulan kunci/nilai yang dapat digunakan untuk berbagi data dalam cakupan koneksi ini. Data dapat disimpan dalam koleksi ini dan akan bertahan untuk koneksi di berbagai pemanggilan metode hub. |
| Features | Mendapatkan koleksi fitur yang tersedia pada koneksi. Untuk saat ini, koleksi ini tidak diperlukan dalam sebagian besar skenario, sehingga belum didokumenkan secara rinci. |
| ConnectionAborted | CancellationToken Mendapatkan yang memberi tahu ketika koneksi dibatalkan. |
Hub.Context juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| GetHttpContext | Mengembalikan HttpContext untuk koneksi, atau null jika koneksi tidak terkait dengan permintaan HTTP. Untuk koneksi HTTP, Anda dapat menggunakan metode ini untuk mendapatkan informasi seperti header HTTP dan string kueri. |
| Abort | Membatalkan koneksi. |
Objek Klien
Kelas Hub memiliki Clients properti yang berisi properti berikut untuk komunikasi antara server dan klien:
| Properti | Deskripsi |
|---|---|
| All | Memanggil metode pada semua klien yang terhubung |
| Caller | Memanggil metode pada klien yang memanggil metode hub |
| Others | Memanggil metode pada semua klien yang terhubung kecuali klien yang memanggil metode |
Hub.Clients juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| AllExcept | Memanggil metode pada semua klien yang terhubung kecuali untuk koneksi yang ditentukan |
| Client | Memanggil metode pada klien tertentu yang terhubung |
| Clients | Memanggil metode pada klien tertentu yang terhubung |
| Group | Memanggil metode pada semua koneksi dalam grup yang ditentukan |
| GroupExcept | Memanggil metode pada semua koneksi dalam grup yang ditentukan, kecuali koneksi yang ditentukan |
| Groups | Memanggil metode pada beberapa grup koneksi |
| OthersInGroup | Memanggil metode pada sekelompok koneksi, tidak termasuk klien yang memanggil metode hub |
| User | Memanggil metode pada semua koneksi yang terkait dengan pengguna tertentu |
| Users | Memanggil metode pada semua koneksi yang terkait dengan pengguna yang ditentukan |
Setiap properti atau metode dalam tabel sebelumnya mengembalikan objek dengan SendAsync metode . Metode ini SendAsync memungkinkan Anda untuk memberikan nama dan parameter metode klien untuk dipanggil.
Mengirim pesan ke klien
Untuk melakukan panggilan ke klien tertentu, gunakan properti Clients objek . Dalam contoh berikut, ada tiga metode Hub:
SendMessagemengirim pesan ke semua klien yang terhubung, menggunakanClients.All.SendMessageToCallermengirim pesan kembali ke pemanggil, menggunakanClients.Caller.SendMessageToGroupmengirim pesan ke semua klien dalamSignalR Usersgrup.
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string user, string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}
Hub yang sangat ditik
Kelemahan penggunaan SendAsync adalah mengandalkan string ajaib untuk menentukan metode klien yang akan dipanggil. Ini membuat kode terbuka untuk kesalahan runtime jika nama metode salah eja atau hilang dari klien.
Alternatif untuk menggunakan SendAsync adalah mengetik Hub dengan kuat dengan Hub<T>. Dalam contoh berikut, ChatHub metode klien telah diekstraksi ke antarmuka yang disebut IChatClient.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Antarmuka ini dapat digunakan untuk merefaktor contoh sebelumnya ChatHub :
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.ReceiveMessage(user, message);
}
}
Menggunakan Hub<IChatClient> memungkinkan pemeriksaan waktu kompilasi metode klien. Ini mencegah masalah yang disebabkan oleh penggunaan string ajaib, karena Hub<T> hanya dapat menyediakan akses ke metode yang ditentukan dalam antarmuka.
Menggunakan jenis yang sangat Hub<T> menonaktifkan kemampuan untuk menggunakan SendAsync. Metode apa pun yang ditentukan pada antarmuka masih dapat didefinisikan sebagai asinkron. Bahkan, masing-masing metode ini harus mengembalikan Task. Karena ini adalah antarmuka, jangan gunakan async kata kunci . Contohnya:
public interface IClient
{
Task ClientMethod();
}
Catatan
Akhiran Async tidak dilucuti dari nama metode. Kecuali metode klien Anda didefinisikan dengan .on('MyMethodAsync'), Anda tidak boleh menggunakan MyMethodAsync sebagai nama.
Mengubah nama metode hub
Secara default, nama metode hub server adalah nama metode .NET. Namun, Anda dapat menggunakan atribut HubMethodName untuk mengubah default ini dan secara manual menentukan nama untuk metode tersebut. Klien harus menggunakan nama ini, alih-alih nama metode .NET, saat memanggil metode :
[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}
Menangani peristiwa untuk koneksi
SignalR Hubs API menyediakan OnConnectedAsync metode virtual dan OnDisconnectedAsync untuk mengelola dan melacak koneksi. Ambil alih OnConnectedAsync metode virtual untuk melakukan tindakan saat klien terhubung ke Hub, seperti menambahkannya ke grup:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
Ambil alih OnDisconnectedAsync metode virtual untuk melakukan tindakan saat klien terputus. Jika klien memutuskan sambungan dengan sengaja (dengan memanggil connection.stop(), misalnya), exception parameternya adalah null. Namun, jika klien terputus karena kesalahan (seperti kegagalan jaringan), exception parameter akan berisi pengecualian yang menjelaskan kegagalan:
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
Peringatan
Peringatan keamanan: Mengekspos ConnectionId dapat menyebabkan peniruan berbahaya jika SignalR versi server atau klien ASP.NET Core 2.2 atau yang lebih lama.
Menangani kesalahan
Pengecualian yang dilemparkan dalam metode hub Anda dikirim ke klien yang memanggil metode . Pada klien JavaScript, invoke metode mengembalikan JavaScript Promise. Ketika klien menerima kesalahan dengan handler yang melekat pada janji menggunakan catch, klien dipanggil dan diteruskan sebagai objek JavaScript Error :
connection.invoke("SendMessage", user, message).catch(err => console.error(err));
Jika Hub Anda memberikan pengecualian, koneksi tidak ditutup. Secara default, SignalR mengembalikan pesan kesalahan generik ke klien. Contohnya:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.
Pengecualian tak terduga sering berisi informasi sensitif, seperti nama server database dalam pengecualian yang dipicu ketika koneksi database gagal. SignalR tidak mengekspos pesan kesalahan terperinci ini secara default sebagai langkah keamanan. Untuk informasi selengkapnya tentang mengapa detail pengecualian ditekan, lihat Pertimbangan keamanan di ASP.NET Core SignalR.
Jika Anda memiliki kondisi luar biasa yang ingin Anda sebarkan ke klien, Anda dapat menggunakan HubException kelas . Jika Anda melempar HubException dari metode hub Anda, SignalRakan mengirim seluruh pesan ke klien, tidak dimodifikasi:
public Task ThrowException()
{
throw new HubException("This error will be sent to the client!");
}
Catatan
SignalR hanya mengirim Message properti pengecualian ke klien. Jejak tumpukan dan properti lain pada pengecualian tidak tersedia untuk klien.
Sumber Daya Tambahan:
Oleh Rachel Appel dan Kevin Griffin
SignalR Hubs API memungkinkan klien yang terhubung untuk memanggil metode di server. Server mendefinisikan metode yang dipanggil dari klien dan klien menentukan metode yang dipanggil dari server. SignalR mengurus semua yang diperlukan untuk memungkinkan komunikasi klien-ke-server dan server-ke-klien secara real-time.
Mengonfigurasi SignalR hub
Untuk mendaftarkan layanan yang diperlukan oleh SignalR hub, hubungi AddSignalR di Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
Untuk mengonfigurasi SignalR titik akhir, panggil MapHub, juga di Program.cs:
app.MapRazorPages();
app.MapHub<ChatHub>("/Chat");
app.Run();
Membuat dan menggunakan hub
Buat hub dengan mendeklarasikan kelas yang mewarisi dari Hub. Tambahkan public metode ke kelas untuk membuatnya dapat dipanggil dari klien:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Catatan
Hub bersifat sementara:
- Jangan menyimpan status di properti kelas hub. Setiap panggilan metode hub dijalankan pada instans hub baru.
- Gunakan
awaitsaat memanggil metode asinkron yang bergantung pada hub tetap hidup. Misalnya, metode sepertiClients.All.SendAsync(...)dapat gagal jika dipanggil tanpaawaitdan metode hub selesai sebelumSendAsyncselesai.
Objek Konteks
Kelas Hub menyertakan Context properti yang berisi properti berikut dengan informasi tentang koneksi:
| Properti | Deskripsi |
|---|---|
| ConnectionId | Mendapatkan ID unik untuk koneksi, yang ditetapkan oleh SignalR. Ada satu ID koneksi untuk setiap koneksi. |
| UserIdentifier | Mendapatkan pengidentifikasi pengguna. Secara default, SignalR menggunakan ClaimTypes.NameIdentifier dari yang ClaimsPrincipal terkait dengan koneksi sebagai pengidentifikasi pengguna. |
| User | Mendapatkan yang ClaimsPrincipal terkait dengan pengguna saat ini. |
| Items | Mendapatkan kumpulan kunci/nilai yang dapat digunakan untuk berbagi data dalam cakupan koneksi ini. Data dapat disimpan dalam koleksi ini dan akan bertahan untuk koneksi di berbagai pemanggilan metode hub. |
| Features | Mendapatkan koleksi fitur yang tersedia pada koneksi. Untuk saat ini, koleksi ini tidak diperlukan dalam sebagian besar skenario, sehingga belum didokumenkan secara rinci. |
| ConnectionAborted | CancellationToken Mendapatkan yang memberi tahu ketika koneksi dibatalkan. |
Hub.Context juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| GetHttpContext | Mengembalikan HttpContext untuk koneksi, atau null jika koneksi tidak terkait dengan permintaan HTTP. Untuk koneksi HTTP, gunakan metode ini untuk mendapatkan informasi seperti header HTTP dan string kueri. |
| Abort | Membatalkan koneksi. |
Objek Klien
Kelas Hub menyertakan Clients properti yang berisi properti berikut untuk komunikasi antara server dan klien:
| Properti | Deskripsi |
|---|---|
| All | Memanggil metode pada semua klien yang terhubung |
| Caller | Memanggil metode pada klien yang memanggil metode hub |
| Others | Memanggil metode pada semua klien yang terhubung kecuali klien yang memanggil metode |
Hub.Clients juga berisi metode berikut:
| Metode | Deskripsi |
|---|---|
| AllExcept | Memanggil metode pada semua klien yang terhubung kecuali untuk koneksi yang ditentukan |
| Client | Memanggil metode pada klien tertentu yang terhubung |
| Clients | Memanggil metode pada klien tertentu yang terhubung |
| Group | Memanggil metode pada semua koneksi dalam grup yang ditentukan |
| GroupExcept | Memanggil metode pada semua koneksi dalam grup yang ditentukan, kecuali koneksi yang ditentukan |
| Groups | Memanggil metode pada beberapa grup koneksi |
| OthersInGroup | Memanggil metode pada sekelompok koneksi, tidak termasuk klien yang memanggil metode hub |
| User | Memanggil metode pada semua koneksi yang terkait dengan pengguna tertentu |
| Users | Memanggil metode pada semua koneksi yang terkait dengan pengguna yang ditentukan |
Setiap properti atau metode dalam tabel sebelumnya mengembalikan objek dengan SendAsync metode . Metode ini SendAsync menerima nama metode klien untuk dipanggil dan parameter apa pun.
Objek yang Client dikembalikan oleh metode dan Caller juga berisi InvokeAsync metode , yang dapat digunakan untuk menunggu hasil dari klien.
Mengirim pesan ke klien
Untuk melakukan panggilan ke klien tertentu, gunakan properti Clients objek . Dalam contoh berikut, ada tiga metode hub:
SendMessagemengirim pesan ke semua klien yang terhubung, menggunakanClients.All.SendMessageToCallermengirim pesan kembali ke pemanggil, menggunakanClients.Caller.SendMessageToGroupmengirim pesan ke semua klien dalamSignalR Usersgrup.
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
Hub yang sangat ditik
Kelemahan penggunaan SendAsync adalah mengandalkan string untuk menentukan metode klien yang akan dipanggil. Ini membuat kode terbuka untuk kesalahan runtime jika nama metode salah eja atau hilang dari klien.
Alternatif untuk menggunakan SendAsync adalah mengetik Hub kelas dengan kuat.Hub<T> Dalam contoh berikut, ChatHub metode klien telah diekstraksi ke dalam antarmuka yang disebut IChatClient:
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Antarmuka ini dapat digunakan untuk merefaktor ChatHub contoh sebelumnya untuk diketik dengan kuat:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
=> await Clients.All.ReceiveMessage(user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.ReceiveMessage(user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").ReceiveMessage(user, message);
}
Menggunakan Hub<IChatClient> memungkinkan pemeriksaan waktu kompilasi metode klien. Ini mencegah masalah yang disebabkan oleh penggunaan string, karena Hub<T> hanya dapat menyediakan akses ke metode yang ditentukan dalam antarmuka. Menggunakan jenis yang sangat Hub<T> menonaktifkan kemampuan untuk menggunakan SendAsync.
Catatan
Akhiran Async tidak dilucuti dari nama metode. Kecuali metode klien didefinisikan dengan .on('MyMethodAsync'), jangan gunakan MyMethodAsync sebagai nama.
Hasil klien
Selain melakukan panggilan ke klien, server dapat meminta hasil dari klien. Ini mengharuskan server untuk menggunakan ISingleClientProxy.InvokeAsync dan klien untuk mengembalikan hasil dari handler-nya .On .
Ada dua cara untuk menggunakan API di server, yang pertama adalah memanggil Client(...) atau Caller pada Clients properti dalam metode Hub:
public class ChatHub : Hub
{
public async Task<string> WaitForMessage(string connectionId)
{
var message = await Clients.Client(connectionId).InvokeAsync<string>(
"GetMessage");
return message;
}
}
Catatan
Menggunakan InvokeAsync dari metode Hub memerlukan pengaturan MaximumParallelInvocationsPerClient opsi ke nilai yang lebih besar dari 1.
Ini akan ditangani dalam rilis mendatang. Untuk informasi selengkapnya, lihat Dukungan mengembalikan nilai dari pemanggilan klien.
Cara kedua adalah memanggil Client(...) instans :IHubContext<T>
async Task SomeMethod(IHubContext<MyHub> context)
{
string result = await context.Clients.Client(connectionID).InvokeAsync<string>(
"GetMessage");
}
Hub yang sangat ditik juga dapat mengembalikan nilai dari metode antarmuka:
public interface IClient
{
Task<string> GetMessage();
}
public class ChatHub : Hub<IClient>
{
public async Task<string> WaitForMessage(string connectionId)
{
string message = await Clients.Client(connectionId).GetMessage();
return message;
}
}
Klien mengembalikan hasil dalam handler mereka .On(...) , seperti yang ditunjukkan di bawah ini:
Klien .NET
hubConnection.On("GetMessage", async () =>
{
Console.WriteLine("Enter message:");
var message = await Console.In.ReadLineAsync();
return message;
});
Klien typescript
hubConnection.on("GetMessage", async () => {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("message");
}, 100);
});
return promise;
});
Catatan
Hasil klien tidak berfungsi dengan Layanan Azure SignalR .
Ini akan ditangani dalam rilis mendatang. Untuk informasi selengkapnya, lihat Dukungan mengembalikan nilai dari pemanggilan klien.
Mengubah nama metode hub
Secara default, nama metode hub server adalah nama metode .NET. Untuk mengubah perilaku default ini untuk metode tertentu, gunakan atribut HubMethodName . Klien harus menggunakan nama ini alih-alih nama metode .NET saat memanggil metode :
[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
=> await Clients.User(user).SendAsync("ReceiveMessage", user, message);
Menyuntikkan layanan ke hub
Konstruktor hub dapat menerima layanan dari DI sebagai parameter, yang dapat disimpan dalam properti di kelas untuk digunakan dalam metode hub.
Saat menyuntikkan beberapa layanan untuk metode hub yang berbeda atau sebagai cara alternatif menulis kode, metode hub juga dapat menerima layanan dari DI. Secara default, parameter metode hub diperiksa dan diselesaikan dari DI jika memungkinkan.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message, IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Jika resolusi implisit parameter dari layanan tidak diinginkan, nonaktifkan dengan DisableImplicitFromServicesParameters.
Untuk secara eksplisit menentukan parameter mana yang diselesaikan dari DI dalam metode hub, gunakan DisableImplicitFromServicesParameters opsi dan gunakan [FromServices] atribut atau atribut kustom yang mengimplementasikan IFromServiceMetadata pada parameter metode hub yang harus diselesaikan dari DI.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
services.AddSignalR(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message,
[FromServices] IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Catatan
Fitur ini memanfaatkan IServiceProviderIsService, yang secara opsional diimplementasikan oleh implementasi DI. Jika kontainer DI aplikasi tidak mendukung fitur ini, menyuntikkan layanan ke metode hub tidak didukung.
Menangani peristiwa untuk koneksi
SignalR Hubs API menyediakan OnConnectedAsync metode virtual dan OnDisconnectedAsync untuk mengelola dan melacak koneksi. Ambil alih OnConnectedAsync metode virtual untuk melakukan tindakan saat klien terhubung ke hub, seperti menambahkannya ke grup:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
Ambil alih OnDisconnectedAsync metode virtual untuk melakukan tindakan saat klien terputus. Jika klien memutuskan sambungan dengan sengaja, seperti dengan memanggil connection.stop(), exception parameter diatur ke null. Namun, jika klien terputus karena kesalahan, seperti kegagalan jaringan, exception parameter berisi pengecualian yang menjelaskan kegagalan:
public override async Task OnDisconnectedAsync(Exception? exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
Menangani kesalahan
Pengecualian yang dilemparkan dalam metode hub dikirim ke klien yang memanggil metode . Pada klien JavaScript, invoke metode mengembalikan JavaScript Promise. Klien dapat melampirkan catch handler ke janji yang dikembalikan atau digunakan trycatch/dengan async/await untuk menangani pengecualian:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Koneksi tidak ditutup saat hub melemparkan pengecualian. Secara default, SignalR mengembalikan pesan kesalahan generik ke klien, seperti yang ditunjukkan dalam contoh berikut:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'SendMessage' on the server.
Pengecualian tak terduga sering berisi informasi sensitif, seperti nama server database dalam pengecualian yang dipicu saat koneksi database gagal. SignalR tidak mengekspos pesan kesalahan terperinci ini secara default sebagai langkah keamanan. Untuk informasi selengkapnya tentang mengapa detail pengecualian ditekan, lihat Pertimbangan keamanan di ASP.NET Core SignalR.
Jika kondisi luar biasa harus disebarluaskan ke klien, gunakan HubException kelas . HubException Jika dilemparkan dalam metode hub, SignalRmengirim seluruh pesan pengecualian ke klien, tidak dimodifikasi:
public Task ThrowException()
=> throw new HubException("This error will be sent to the client!");
Catatan
SignalR hanya mengirim Message properti pengecualian ke klien. Jejak tumpukan dan properti lain pada pengecualian tidak tersedia untuk klien.