Panduan API ASP.NET SignalR Hubs - Server (C#)
oleh Patrick Fletcher, Tom Dykstra
Peringatan
Dokumentasi ini bukan untuk versi terbaru SignalR. Lihatlah ASP.NET Core SignalR.
Dokumen ini menyediakan pengantar pemrograman sisi server ASP.NET SignalR Hubs API untuk SignalR versi 2, dengan sampel kode yang menunjukkan opsi umum.
SIGNALR Hubs API memungkinkan Anda melakukan panggilan prosedur jarak jauh (RPC) dari server ke klien yang terhubung dan dari klien ke server. Dalam kode server, Anda menentukan metode yang dapat dipanggil oleh klien, dan Anda memanggil metode yang berjalan pada klien. Dalam kode klien, Anda menentukan metode yang dapat dipanggil dari server, dan Anda memanggil metode yang berjalan di server. SignalR menangani semua pipa klien-ke-server untuk Anda.
SignalR juga menawarkan API tingkat bawah yang disebut Koneksi Persisten. Untuk pengenalan SignalR, Hub, dan Koneksi Persisten, lihat Pengantar SignalR 2.
Versi perangkat lunak yang digunakan dalam topik ini
- Visual Studio 2013
- .NET 4.5
- SignalR versi 2
Versi topik
Untuk informasi tentang versi SignalR yang lebih lama, lihat Versi Lama SignalR.
Pertanyaan dan komentar
Silakan tinggalkan umpan balik tentang bagaimana Anda menyukai tutorial ini dan apa yang dapat kami tingkatkan di komentar di bagian bawah halaman. Jika Anda memiliki pertanyaan yang tidak terkait langsung dengan tutorial, Anda dapat mempostingnya ke forum ASP.NET SignalR atau StackOverflow.com.
Gambaran Umum
Dokumen ini berisi bagian berikut:
Cara menentukan metode di kelas Hub yang dapat dipanggil klien
Cara mendapatkan informasi tentang klien dari properti Konteks
Cara memanggil metode klien dan mengelola grup dari luar kelas Hub
Untuk dokumentasi tentang cara memprogram klien, lihat sumber daya berikut:
Komponen server untuk SignalR 2 hanya tersedia di .NET 4.5. Server yang menjalankan .NET 4.0 harus menggunakan SignalR v1.x.
Cara mendaftarkan middleware SignalR
Untuk menentukan rute yang akan digunakan klien untuk terhubung ke Hub Anda, panggil MapSignalR
metode saat aplikasi dimulai. MapSignalR
adalah metode ekstensi untuk OwinExtensions
kelas . Contoh berikut menunjukkan cara menentukan rute SignalR Hubs menggunakan kelas startup OWIN.
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
}
Jika Anda menambahkan fungsionalitas SignalR ke aplikasi MVC ASP.NET, pastikan rute SignalR ditambahkan sebelum rute lainnya. Untuk informasi selengkapnya, lihat Tutorial: Memulai SignalR 2 dan MVC 5.
The /signalr URL
Secara default, URL rute yang akan digunakan klien untuk terhubung ke Hub Anda adalah "/signalr". (Jangan bingung dengan URL ini dengan URL "/signalr/hubs", yaitu untuk file JavaScript yang dihasilkan secara otomatis. Untuk informasi selengkapnya tentang proksi yang dihasilkan, lihat Panduan API SignalR Hubs - Klien JavaScript - Proksi yang dihasilkan dan apa fungsinya untuk Anda.)
Mungkin ada keadaan luar biasa yang membuat URL dasar ini tidak dapat digunakan untuk SignalR; misalnya, Anda memiliki folder di proyek bernama signalr dan Anda tidak ingin mengubah namanya. Dalam hal ini, Anda dapat mengubah URL dasar, seperti yang ditunjukkan dalam contoh berikut (ganti "/signalr" dalam kode sampel dengan URL yang Anda inginkan).
Kode server yang menentukan URL
app.MapSignalR("/signalr", new HubConfiguration());
Kode klien JavaScript yang menentukan URL (dengan proksi yang dihasilkan)
$.connection.hub.url = "/signalr"
$.connection.hub.start().done(init);
Kode klien JavaScript yang menentukan URL (tanpa proksi yang dihasilkan)
var connection = $.hubConnection("/signalr", { useDefaultPath: false });
Kode klien .NET yang menentukan URL
var hubConnection = new HubConnection("http://contoso.com/signalr", useDefaultUrl: false);
Mengonfigurasi Opsi SignalR
Kelebihan beban MapSignalR
metode memungkinkan Anda menentukan URL kustom, pemecah masalah dependensi kustom, dan opsi berikut:
Aktifkan panggilan lintas domain menggunakan CORS atau JSONP dari klien browser.
Biasanya jika browser memuat halaman dari
http://contoso.com
, koneksi SignalR berada di domain yang sama, dihttp://contoso.com/signalr
. Jika halaman darihttp://contoso.com
membuat koneksi kehttp://fabrikam.com/signalr
, itu adalah koneksi lintas domain. Untuk alasan keamanan, koneksi lintas domain dinonaktifkan secara default. Untuk informasi selengkapnya, lihat ASP.NET Panduan API SignalR Hubs - Klien JavaScript - Cara membuat koneksi lintas domain.Aktifkan pesan kesalahan terperinci.
Ketika kesalahan terjadi, perilaku default SignalR adalah mengirim pesan pemberitahuan kepada klien tanpa detail tentang apa yang terjadi. Mengirim informasi kesalahan terperinci ke klien tidak disarankan dalam produksi, karena pengguna jahat mungkin dapat menggunakan informasi dalam serangan terhadap aplikasi Anda. Untuk pemecahan masalah, Anda dapat menggunakan opsi ini untuk mengaktifkan pelaporan kesalahan yang lebih informatif untuk sementara waktu.
Nonaktifkan file proksi JavaScript yang dihasilkan secara otomatis.
Secara default, file JavaScript dengan proksi untuk kelas Hub Anda dihasilkan sebagai respons terhadap URL "/signalr/hubs". Jika Anda tidak ingin menggunakan proksi JavaScript, atau jika Anda ingin membuat file ini secara manual dan merujuk ke file fisik di klien Anda, Anda dapat menggunakan opsi ini untuk menonaktifkan pembuatan proksi. Untuk informasi selengkapnya, lihat Panduan API SignalR Hubs - Klien JavaScript - Cara membuat file fisik untuk proksi yang dihasilkan SignalR.
Contoh berikut menunjukkan cara menentukan URL koneksi SignalR dan opsi ini dalam panggilan ke MapSignalR
metode . Untuk menentukan URL kustom, ganti "/signalr" dalam contoh dengan URL yang ingin Anda gunakan.
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
hubConfiguration.EnableJavaScriptProxies = false;
app.MapSignalR("/signalr", hubConfiguration);
Cara membuat dan menggunakan kelas Hub
Untuk membuat Hub, buat kelas yang berasal dari Microsoft.Aspnet.Signalr.Hub. Contoh berikut menunjukkan kelas Hub sederhana untuk aplikasi obrolan.
public class ContosoChatHub : Hub
{
public async Task NewContosoChatMessage(string name, string message)
{
await Clients.All.addNewMessageToPage(name, message);
}
}
Dalam contoh ini, klien yang terhubung dapat memanggil NewContosoChatMessage
metode , dan ketika itu terjadi, data yang diterima disiarkan ke semua klien yang terhubung.
Masa pakai objek hub
Anda tidak membuat instans kelas Hub atau memanggil metodenya dari kode Anda sendiri di server; semua yang dilakukan untuk Anda oleh alur SignalR Hubs. SignalR membuat instans baru kelas Hub Anda setiap kali perlu menangani operasi Hub seperti saat klien terhubung, memutuskan sambungan, atau melakukan panggilan metode ke server.
Karena instans kelas Hub bersifat sementara, Anda tidak dapat menggunakannya untuk mempertahankan status dari satu panggilan metode ke panggilan berikutnya. Setiap kali server menerima panggilan metode dari klien, instans baru kelas Hub Anda memproses pesan. Untuk mempertahankan status melalui beberapa koneksi dan panggilan metode, gunakan beberapa metode lain seperti database, atau variabel statis pada kelas Hub, atau kelas berbeda yang tidak berasal dari Hub
. Jika Anda mempertahankan data dalam memori, menggunakan metode seperti variabel statis pada kelas Hub, data akan hilang saat domain aplikasi didaur ulang.
Jika Anda ingin mengirim pesan ke klien dari kode Anda sendiri yang berjalan di luar kelas Hub, Anda tidak dapat melakukannya dengan membuat instans kelas Hub, tetapi Anda dapat melakukannya dengan mendapatkan referensi ke objek konteks SignalR untuk kelas Hub Anda. Untuk informasi selengkapnya, lihat Cara memanggil metode klien dan mengelola grup dari luar kelas Hub nanti dalam topik ini.
Camel-casing nama Hub di klien JavaScript
Secara default, klien JavaScript merujuk ke Hub dengan menggunakan versi camel-cased dari nama kelas. SignalR secara otomatis membuat perubahan ini sehingga kode JavaScript dapat sesuai dengan konvensi JavaScript. Contoh sebelumnya akan disebut sebagai contosoChatHub
dalam kode JavaScript.
Server
public class ContosoChatHub : Hub
Klien JavaScript menggunakan proksi yang dihasilkan
var contosoChatHubProxy = $.connection.contosoChatHub;
Jika Anda ingin menentukan nama yang berbeda untuk digunakan klien, tambahkan HubName
atribut . Saat Anda menggunakan HubName
atribut , tidak ada perubahan nama pada camel case pada klien JavaScript.
Server
[HubName("PascalCaseContosoChatHub")]
public class ContosoChatHub : Hub
Klien JavaScript menggunakan proksi yang dihasilkan
var contosoChatHubProxy = $.connection.PascalCaseContosoChatHub;
Beberapa Hub
Anda dapat menentukan beberapa kelas Hub dalam aplikasi. Saat Anda melakukannya, koneksi dibagikan tetapi grup terpisah:
Semua klien akan menggunakan URL yang sama untuk membuat koneksi SignalR dengan layanan Anda ("/signalr" atau URL kustom Anda jika Anda menentukannya), dan koneksi tersebut digunakan untuk semua Hub yang ditentukan oleh layanan.
Tidak ada perbedaan performa untuk beberapa Hub dibandingkan dengan menentukan semua fungsi hub dalam satu kelas.
Semua Hub mendapatkan informasi permintaan HTTP yang sama.
Karena semua Hub berbagi koneksi yang sama, satu-satunya informasi permintaan HTTP yang didapat server adalah apa yang datang dalam permintaan HTTP asli yang membuat koneksi SignalR. Jika Anda menggunakan permintaan koneksi untuk meneruskan informasi dari klien ke server dengan menentukan string kueri, Anda tidak dapat menyediakan string kueri yang berbeda ke Hub yang berbeda. Semua Hub akan menerima informasi yang sama.
File proksi JavaScript yang dihasilkan akan berisi proksi untuk semua Hub dalam satu file.
Untuk informasi tentang proksi JavaScript, lihat Panduan API SignalR Hubs - Klien JavaScript - Proksi yang dihasilkan dan apa yang dilakukannya untuk Anda.
Grup ditentukan dalam Hub.
Di SignalR, Anda dapat menentukan grup bernama untuk disiarkan ke subset klien yang terhubung. Grup dipertahankan secara terpisah untuk setiap Hub. Misalnya, grup bernama "Administrator" akan menyertakan satu set klien untuk kelas Anda
ContosoChatHub
, dan nama grup yang sama akan merujuk ke sekumpulan klien yang berbeda untuk kelas AndaStockTickerHub
.
Strongly-Typed Hubs
Untuk menentukan antarmuka untuk metode hub yang dapat direferensikan klien Anda (dan mengaktifkan Intellisense pada metode hub Anda), dapatkan hub Anda dari Hub<T>
(diperkenalkan di SignalR 2.1) daripada Hub
:
public class StrongHub : Hub<IClient>
{
public async Task Send(string message)
{
await Clients.All.NewMessage(message);
}
}
public interface IClient
{
Task NewMessage(string message);
}
Cara menentukan metode di kelas Hub yang dapat dipanggil klien
Untuk mengekspos metode di Hub yang ingin Anda panggil dari klien, nyatakan metode publik, seperti yang ditunjukkan dalam contoh berikut.
public class ContosoChatHub : Hub
{
public async Task NewContosoChatMessage(string name, string message)
{
await Clients.All.addNewMessageToPage(name, message);
}
}
public class StockTickerHub : Hub
{
public IEnumerable<Stock> GetAllStocks()
{
return _stockTicker.GetAllStocks();
}
}
Anda dapat menentukan jenis pengembalian dan parameter, termasuk jenis dan array kompleks, seperti yang Anda lakukan dalam metode C# apa pun. Data apa pun yang Anda terima dalam parameter atau kembali ke pemanggil dikomunikasikan antara klien dan server dengan menggunakan JSON, dan SignalR menangani pengikatan objek kompleks dan array objek secara otomatis.
Camel-casing nama metode di klien JavaScript
Secara default, klien JavaScript merujuk ke metode Hub dengan menggunakan versi camel-cased dari nama metode. SignalR secara otomatis membuat perubahan ini sehingga kode JavaScript dapat sesuai dengan konvensi JavaScript.
Server
public void NewContosoChatMessage(string userName, string message)
Klien JavaScript menggunakan proksi yang dihasilkan
contosoChatHubProxy.server.newContosoChatMessage(userName, message);
Jika Anda ingin menentukan nama yang berbeda untuk digunakan klien, tambahkan HubMethodName
atribut .
Server
[HubMethodName("PascalCaseNewContosoChatMessage")]
public void NewContosoChatMessage(string userName, string message)
Klien JavaScript menggunakan proksi yang dihasilkan
contosoChatHubProxy.server.PascalCaseNewContosoChatMessage(userName, message);
Kapan harus mengeksekusi secara asinkron
Jika metode akan berjalan lama atau harus melakukan pekerjaan yang akan melibatkan penantian, seperti pencarian database atau panggilan layanan web, buat metode Hub asinkron dengan mengembalikan Tugas (sebagai ganti void
pengembalian) atau objek Task<T> (sebagai ganti T
jenis pengembalian). Ketika Anda mengembalikan Task
objek dari metode , SignalR menunggu Task
hingga selesai, dan kemudian mengirimkan hasil yang dibongkar kembali ke klien, sehingga tidak ada perbedaan dalam cara Anda membuat kode panggilan metode di klien.
Membuat metode Hub asinkron menghindari pemblokiran koneksi saat menggunakan transportasi WebSocket. Ketika metode Hub dijalankan secara sinkron dan transportasinya adalah WebSocket, pemanggilan metode berikutnya di Hub dari klien yang sama diblokir sampai metode Hub selesai.
Contoh berikut menunjukkan metode yang sama yang dikodekan untuk berjalan secara sinkron atau asinkron, diikuti oleh kode klien JavaScript yang berfungsi untuk memanggil salah satu versi.
Sinkron
public IEnumerable<Stock> GetAllStocks()
{
// Returns data from memory.
return _stockTicker.GetAllStocks();
}
Asinkron
public async Task<IEnumerable<Stock>> GetAllStocks()
{
// Returns data from a web service.
var uri = Util.getServiceUri("Stocks");
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(uri);
return (await response.Content.ReadAsAsync<IEnumerable<Stock>>());
}
}
Klien JavaScript menggunakan proksi yang dihasilkan
stockTickerHubProxy.server.getAllStocks().done(function (stocks) {
$.each(stocks, function () {
alert(this.Symbol + ' ' + this.Price);
});
});
Untuk informasi selengkapnya tentang cara menggunakan metode asinkron di ASP.NET 4.5, lihat Menggunakan Metode Asinkron di ASP.NET MVC 4.
Menentukan Kelebihan Beban
Jika Anda ingin menentukan kelebihan beban untuk metode , jumlah parameter di setiap kelebihan beban harus berbeda. Jika Anda membedakan kelebihan beban hanya dengan menentukan jenis parameter yang berbeda, kelas Hub Anda akan dikompilasi tetapi layanan SignalR akan melemparkan pengecualian pada waktu proses ketika klien mencoba memanggil salah satu kelebihan beban.
Melaporkan kemajuan dari pemanggilan metode hub
SignalR 2.1 menambahkan dukungan untuk pola pelaporan kemajuan yang diperkenalkan di .NET 4.5. Untuk menerapkan pelaporan kemajuan, tentukan IProgress<T>
parameter untuk metode hub yang dapat diakses klien Anda:
public class ProgressHub : Hub
{
public async Task<string> DoLongRunningThing(IProgress<int> progress)
{
for (int i = 0; i <= 100; i+=5)
{
await Task.Delay(200);
progress.Report(i);
}
return "Job complete!";
}
}
Saat menulis metode server yang berjalan lama, penting untuk menggunakan pola pemrograman asinkron seperti Asinkron/ Tunggu daripada memblokir utas hub.
Cara memanggil metode klien dari kelas Hub
Untuk memanggil metode klien dari server, gunakan Clients
properti dalam metode di kelas Hub Anda. Contoh berikut menunjukkan kode server yang memanggil addNewMessageToPage
semua klien yang terhubung, dan kode klien yang menentukan metode dalam klien JavaScript.
Server
public class ContosoChatHub : Hub
{
public async Task NewContosoChatMessage(string name, string message)
{
await Clients.All.addNewMessageToPage(name, message);
}
}
Memanggil metode klien adalah operasi asinkron dan mengembalikan Task
. Gunakan await
:
- Untuk memastikan pesan dikirim tanpa kesalahan.
- Untuk mengaktifkan penangkapan dan penanganan kesalahan di blok try-catch.
Klien JavaScript menggunakan proksi yang dihasilkan
contosoChatHubProxy.client.addNewMessageToPage = function (name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '<li>');
};
Anda tidak bisa mendapatkan nilai pengembalian dari metode klien; sintaks seperti int x = Clients.All.add(1,1)
tidak berfungsi.
Anda dapat menentukan jenis kompleks dan array untuk parameter. Contoh berikut meneruskan jenis kompleks ke klien dalam parameter metode.
Kode server yang memanggil metode klien menggunakan objek kompleks
public async Task SendMessage(string name, string message)
{
await Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });
}
Kode server yang menentukan objek kompleks
public class ContosoChatMessage
{
public string UserName { get; set; }
public string Message { get; set; }
}
Klien JavaScript menggunakan proksi yang dihasilkan
var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addMessageToPage = function (message) {
console.log(message.UserName + ' ' + message.Message);
});
Memilih klien mana yang akan menerima RPC
Properti Klien mengembalikan objek HubConnectionContext yang menyediakan beberapa opsi untuk menentukan klien mana yang akan menerima RPC:
Semua klien yang terhubung.
Clients.All.addContosoChatMessageToPage(name, message);
Hanya klien panggilan.
Clients.Caller.addContosoChatMessageToPage(name, message);
Semua klien kecuali klien panggilan.
Clients.Others.addContosoChatMessageToPage(name, message);
Klien tertentu yang diidentifikasi oleh ID koneksi.
Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name, message);
Contoh ini memanggil
addContosoChatMessageToPage
klien panggilan dan memiliki efek yang sama seperti menggunakanClients.Caller
.Semua klien yang terhubung kecuali klien yang ditentukan, diidentifikasi oleh ID koneksi.
Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung dalam grup tertentu.
Clients.Group(groupName).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung dalam grup tertentu kecuali klien yang ditentukan, yang diidentifikasi oleh ID koneksi.
Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung dalam grup tertentu kecuali klien panggilan.
Clients.OthersInGroup(groupName).addContosoChatMessageToPage(name, message);
Pengguna tertentu, yang diidentifikasi oleh userId.
Clients.User(userid).addContosoChatMessageToPage(name, message);
Secara default, ini adalah
IPrincipal.Identity.Name
, tetapi ini dapat diubah dengan mendaftarkan implementasi IUserIdProvider dengan host global.Semua klien dan grup dalam daftar ID koneksi.
Clients.Clients(ConnectionIds).broadcastMessage(name, message);
Daftar grup.
Clients.Groups(GroupIds).broadcastMessage(name, message);
Pengguna berdasarkan nama.
Clients.Client(username).broadcastMessage(name, message);
Daftar nama pengguna (diperkenalkan di SignalR 2.1).
Clients.Users(new string[] { "myUser", "myUser2" }).broadcastMessage(name, message);
Tidak ada validasi waktu kompilasi untuk nama metode
Nama metode yang Anda tentukan ditafsirkan sebagai objek dinamis, yang berarti tidak ada IntelliSense atau validasi waktu kompilasi untuk itu. Ekspresi dievaluasi pada durasi. Ketika panggilan metode dijalankan, SignalR mengirim nama metode dan nilai parameter ke klien, dan jika klien memiliki metode yang cocok dengan nama, metode tersebut dipanggil dan nilai parameter diteruskan ke dalamnya. Jika tidak ada metode pencocokan yang ditemukan pada klien, tidak ada kesalahan yang muncul. Untuk informasi tentang format data yang ditransmisikan SignalR ke klien di belakang layar saat Anda memanggil metode klien, lihat Pengantar SignalR.
Pencocokan nama metode yang tidak peka huruf besar/kecil
Pencocokan nama metode tidak peka huruf besar/kecil. Misalnya, Clients.All.addContosoChatMessageToPage
pada server akan menjalankan AddContosoChatMessageToPage
, , addcontosochatmessagetopage
atau addContosoChatMessageToPage
pada klien.
Eksekusi asinkron
Metode yang Anda panggil dijalankan secara asinkron. Kode apa pun yang muncul setelah panggilan metode ke klien akan segera dijalankan tanpa menunggu SignalR selesai mengirimkan data ke klien kecuali Anda menentukan bahwa baris kode berikutnya harus menunggu penyelesaian metode. Contoh kode berikut menunjukkan cara menjalankan dua metode klien secara berurutan.
Menggunakan Await (.NET 4.5)
public async Task NewContosoChatMessage(string name, string message)
{
await Clients.Others.addContosoChatMessageToPage(data);
await Clients.Caller.notifyMessageSent();
}
Jika Anda menggunakan await
untuk menunggu hingga metode klien selesai sebelum baris kode berikutnya dijalankan, itu tidak berarti bahwa klien akan benar-benar menerima pesan sebelum baris kode berikutnya dijalankan. "Penyelesaian" dari panggilan metode klien hanya berarti bahwa SignalR telah melakukan semua yang diperlukan untuk mengirim pesan. Jika Anda memerlukan verifikasi bahwa klien menerima pesan, Anda harus memprogram mekanisme itu sendiri. Misalnya, Anda dapat membuat MessageReceived
kode metode di Hub, dan dalam addContosoChatMessageToPage
metode pada klien yang dapat Anda panggil MessageReceived
setelah Anda melakukan pekerjaan apa pun yang perlu Anda lakukan pada klien. Di MessageReceived
Hub, Anda dapat melakukan pekerjaan apa pun tergantung pada penerimaan klien yang sebenarnya dan pemrosesan panggilan metode asli.
Cara menggunakan variabel string sebagai nama metode
Jika Anda ingin memanggil metode klien dengan menggunakan variabel string sebagai nama metode, transmisikan Clients.All
(atau Clients.Others
, , Clients.Caller
dll.) ke IClientProxy
lalu panggil Invoke(methodName, args...).
public async Task NewContosoChatMessage(string name, string message)
{
string methodToCall = "addContosoChatMessageToPage";
IClientProxy proxy = Clients.All;
await proxy.Invoke(methodToCall, name, message);
}
Cara mengelola keanggotaan grup dari kelas Hub
Grup di SignalR menyediakan metode untuk menyiarkan pesan ke subset tertentu dari klien yang terhubung. Grup dapat memiliki sejumlah klien, dan klien dapat menjadi anggota dari sejumlah grup.
Untuk mengelola keanggotaan grup, gunakan metode Tambahkan dan Hapus yang disediakan oleh Groups
properti kelas Hub. Contoh berikut menunjukkan Groups.Add
metode dan Groups.Remove
yang digunakan dalam metode Hub yang dipanggil oleh kode klien, diikuti oleh kode klien JavaScript yang memanggilnya.
Server
public class ContosoChatHub : Hub
{
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
public Task LeaveGroup(string groupName)
{
return Groups.Remove(Context.ConnectionId, groupName);
}
}
Klien JavaScript menggunakan proksi yang dihasilkan
contosoChatHubProxy.server.joinGroup(groupName);
contosoChatHubProxy.server.leaveGroup(groupName);
Anda tidak perlu membuat grup secara eksplisit. Akibatnya grup secara otomatis dibuat saat pertama kali Anda menentukan namanya dalam panggilan ke Groups.Add
, dan grup dihapus saat Anda menghapus koneksi terakhir dari keanggotaan di dalamnya.
Tidak ada API untuk mendapatkan daftar keanggotaan grup atau daftar grup. SignalR mengirim pesan ke klien dan grup berdasarkan model pub/sub, dan server tidak mempertahankan daftar grup atau keanggotaan grup. Ini membantu memaksimalkan skalabilitas, karena setiap kali Anda menambahkan simpul ke farm web, status apa pun yang dipertahankan SignalR harus disebarluaskan ke simpul baru.
Eksekusi asinkron metode Tambahkan dan Hapus
Metode Groups.Add
dan Groups.Remove
dijalankan secara asinkron. Jika Anda ingin menambahkan klien ke grup dan segera mengirim pesan ke klien dengan menggunakan grup, Anda harus memastikan bahwa Groups.Add
metode selesai terlebih dahulu. Contoh kode berikut menunjukkan cara melakukannya.
Menambahkan klien ke grup lalu olahpesan klien tersebut
public async Task JoinGroup(string groupName)
{
await Groups.Add(Context.ConnectionId, groupName);
await Clients.Group(groupname).addContosoChatMessageToPage(Context.ConnectionId + " added to group");
}
Persistensi keanggotaan grup
SignalR melacak koneksi, bukan pengguna, jadi jika Anda ingin pengguna berada dalam grup yang sama setiap kali pengguna membuat koneksi, Anda harus memanggil Groups.Add
setiap kali pengguna membuat koneksi baru.
Setelah hilangnya konektivitas sementara, terkadang SignalR dapat memulihkan koneksi secara otomatis. Dalam hal ini, SignalR memulihkan koneksi yang sama, tidak membuat koneksi baru, sehingga keanggotaan grup klien secara otomatis dipulihkan. Ini dimungkinkan bahkan ketika jeda sementara adalah hasil dari reboot atau kegagalan server, karena status koneksi untuk setiap klien, termasuk keanggotaan grup, disandingkan dengan klien. Jika server tidak berfungsi dan digantikan oleh server baru sebelum waktu koneksi habis, klien dapat terhubung kembali secara otomatis ke server baru dan mendaftar kembali dalam grup tempat server tersebut menjadi anggotanya.
Ketika koneksi tidak dapat dipulihkan secara otomatis setelah hilangnya konektivitas, atau ketika koneksi habis, atau ketika klien terputus (misalnya, ketika browser menavigasi ke halaman baru), keanggotaan grup hilang. Lain kali pengguna tersambung akan menjadi koneksi baru. Untuk mempertahankan keanggotaan grup ketika pengguna yang sama membuat koneksi baru, aplikasi Anda harus melacak asosiasi antara pengguna dan grup, dan memulihkan keanggotaan grup setiap kali pengguna membuat koneksi baru.
Untuk informasi selengkapnya tentang koneksi dan koneksi ulang, lihat Cara menangani peristiwa seumur hidup koneksi di kelas Hub nanti dalam topik ini.
Grup pengguna tunggal
Aplikasi yang menggunakan SignalR biasanya harus melacak hubungan antara pengguna dan koneksi untuk mengetahui pengguna mana yang telah mengirim pesan dan pengguna mana yang harus menerima pesan. Grup digunakan dalam salah satu dari dua pola yang umum digunakan untuk melakukan itu.
Grup pengguna tunggal.
Anda dapat menentukan nama pengguna sebagai nama grup, dan menambahkan ID koneksi saat ini ke grup setiap kali pengguna tersambung atau tersambung kembali. Untuk mengirim pesan kepada pengguna yang Anda kirim ke grup. Kerugian dari metode ini adalah bahwa grup tidak memberi Anda cara untuk mengetahui apakah pengguna online atau offline.
Lacak asosiasi antara nama pengguna dan ID koneksi.
Anda dapat menyimpan hubungan antara setiap nama pengguna dan satu atau beberapa ID koneksi dalam kamus atau database, dan memperbarui data yang disimpan setiap kali pengguna tersambung atau terputus. Untuk mengirim pesan kepada pengguna, Anda menentukan ID koneksi. Kerugian dari metode ini adalah membutuhkan lebih banyak memori.
Cara menangani peristiwa seumur hidup koneksi di kelas Hub
Alasan umum untuk menangani peristiwa seumur hidup koneksi adalah untuk melacak apakah pengguna terhubung atau tidak, dan untuk melacak hubungan antara nama pengguna dan ID koneksi. Untuk menjalankan kode Anda sendiri saat klien terhubung atau memutuskan sambungan, ganti OnConnected
metode virtual , OnDisconnected
, dan OnReconnected
kelas Hub, seperti yang ditunjukkan dalam contoh berikut.
public class ContosoChatHub : Hub
{
public override Task OnConnected()
{
// Add your own code here.
// For example: in a chat application, record the association between
// the current connection ID and user name, and mark the user as online.
// After the code in this method completes, the client is informed that
// the connection is established; for example, in a JavaScript client,
// the start().done callback is executed.
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
// Add your own code here.
// For example: in a chat application, mark the user as offline,
// delete the association between the current connection id and user name.
return base.OnDisconnected(stopCalled);
}
public override Task OnReconnected()
{
// Add your own code here.
// For example: in a chat application, you might have marked the
// user as offline after a period of inactivity; in that case
// mark the user as online again.
return base.OnReconnected();
}
}
Ketika OnConnected, OnDisconnected, dan OnReconnected dipanggil
Setiap kali browser menavigasi ke halaman baru, koneksi baru harus dibuat, yang berarti SignalR akan menjalankan OnDisconnected
metode diikuti dengan OnConnected
metode . SignalR selalu membuat ID koneksi baru saat koneksi baru dibuat.
Metode OnReconnected
ini dipanggil ketika telah ada pemutusan sementara dalam konektivitas yang dapat dipulihkan oleh SignalR secara otomatis, seperti ketika kabel untuk sementara terputus dan terhubung kembali sebelum waktu koneksi habis. Metode OnDisconnected
ini dipanggil ketika klien terputus dan SignalR tidak dapat terhubung kembali secara otomatis, seperti ketika browser menavigasi ke halaman baru. Oleh karena itu, urutan peristiwa yang mungkin untuk klien tertentu adalah OnConnected
, , OnReconnected
OnDisconnected
; atau OnConnected
, OnDisconnected
. Anda tidak akan melihat urutan OnConnected
, , OnDisconnected
OnReconnected
untuk koneksi tertentu.
Metode OnDisconnected
ini tidak dipanggil dalam beberapa skenario, seperti ketika server tidak berfungsi atau Domain Aplikasi didaur ulang. Ketika server lain tersambung atau Domain Aplikasi menyelesaikan daur ulangnya, beberapa klien mungkin dapat menyambungkan kembali dan mengaktifkan peristiwa tersebut OnReconnected
.
Untuk informasi selengkapnya, lihat Memahami dan Menangani Peristiwa Seumur Hidup Koneksi di SignalR.
Status penelepon tidak diisi
Metode penanganan aktivitas seumur hidup koneksi dipanggil dari server, yang berarti bahwa status apa pun yang Anda masukkan ke state
dalam objek pada klien tidak akan diisi di Caller
properti di server. Untuk informasi tentang state
objek dan Caller
properti , lihat Cara meneruskan status antara klien dan kelas Hub nanti dalam topik ini.
Cara mendapatkan informasi tentang klien dari properti Konteks
Untuk mendapatkan informasi tentang klien, gunakan Context
properti kelas Hub. Properti Context
mengembalikan objek HubCallerContext yang menyediakan akses ke informasi berikut:
ID koneksi klien panggilan.
string connectionID = Context.ConnectionId;
ID koneksi adalah GUID yang ditetapkan oleh SignalR (Anda tidak dapat menentukan nilai dalam kode Anda sendiri). Ada satu ID koneksi untuk setiap koneksi, dan ID koneksi yang sama digunakan oleh semua Hub jika Anda memiliki beberapa Hub di aplikasi Anda.
Data header HTTP.
System.Collections.Specialized.NameValueCollection headers = Context.Request.Headers;
Anda juga bisa mendapatkan header HTTP dari
Context.Headers
. Alasan untuk beberapa referensi ke hal yang sama adalah yangContext.Headers
dibuat terlebih dahulu,Context.Request
properti ditambahkan nanti, danContext.Headers
dipertahankan untuk kompatibilitas mundur.Mengkueri data string.
System.Collections.Specialized.NameValueCollection queryString = Context.Request.QueryString; string parameterValue = queryString["parametername"]
Anda juga bisa mendapatkan data string kueri dari
Context.QueryString
.String kueri yang Anda dapatkan di properti ini adalah string yang digunakan dengan permintaan HTTP yang membuat koneksi SignalR. Anda dapat menambahkan parameter string kueri di klien dengan mengonfigurasi koneksi, yang merupakan cara mudah untuk meneruskan data tentang klien dari klien ke server. Contoh berikut menunjukkan salah satu cara untuk menambahkan string kueri di klien JavaScript saat Anda menggunakan proksi yang dihasilkan.
$.connection.hub.qs = { "version" : "1.0" };
Untuk informasi selengkapnya tentang mengatur parameter string kueri, lihat panduan API untuk klien JavaScript dan .NET .
Anda dapat menemukan metode transportasi yang digunakan untuk koneksi dalam data string kueri, bersama dengan beberapa nilai lain yang digunakan secara internal oleh SignalR:
string transportMethod = queryString["transport"];
Nilainya
transportMethod
adalah "webSockets", "serverSentEvents", "foreverFrame" atau "longPolling". Perhatikan bahwa jika Anda memeriksa nilai ini dalamOnConnected
metode penanganan aktivitas, dalam beberapa skenario, Anda mungkin awalnya mendapatkan nilai transportasi yang bukan metode transportasi akhir yang dinegosiasikan untuk koneksi. Dalam hal ini metode akan melemparkan pengecualian dan akan dipanggil lagi nanti ketika metode transportasi akhir ditetapkan.Cookie.
System.Collections.Generic.IDictionary<string, Cookie> cookies = Context.Request.Cookies;
Anda juga bisa mendapatkan cookie dari
Context.RequestCookies
.Informasi pengguna.
System.Security.Principal.IPrincipal user = Context.User;
Objek HttpContext untuk permintaan :
System.Web.HttpContextBase httpContext = Context.Request.GetHttpContext();
Gunakan metode ini alih-alih
HttpContext.Current
mendapatkanHttpContext
objek untuk koneksi SignalR.
Cara melewati status antara klien dan kelas Hub
Proksi klien menyediakan state
objek tempat Anda dapat menyimpan data yang ingin Anda kirimkan ke server dengan setiap panggilan metode. Di server Anda dapat mengakses data ini di Clients.Caller
properti dalam metode Hub yang dipanggil oleh klien. Properti Clients.Caller
tidak diisi untuk metode OnConnected
penanganan aktivitas seumur hidup koneksi , , OnDisconnected
dan OnReconnected
.
Membuat atau memperbarui data dalam state
objek dan Clients.Caller
properti berfungsi di kedua arah. Anda dapat memperbarui nilai di server dan nilai tersebut diteruskan kembali ke klien.
Contoh berikut menunjukkan kode klien JavaScript yang menyimpan status untuk transmisi ke server dengan setiap panggilan metode.
contosoChatHubProxy.state.userName = "Fadi Fakhouri";
contosoChatHubProxy.state.computerName = "fadivm1";
Contoh berikut menunjukkan kode yang setara dalam klien .NET.
contosoChatHubProxy["userName"] = "Fadi Fakhouri";
chatHubProxy["computerName"] = "fadivm1";
Di kelas Hub, Anda dapat mengakses data ini di Clients.Caller
properti . Contoh berikut menunjukkan kode yang mengambil status yang dimaksud dalam contoh sebelumnya.
public async Task NewContosoChatMessage(string data)
{
string userName = Clients.Caller.userName;
string computerName = Clients.Caller.computerName;
await Clients.Others.addContosoChatMessageToPage(message, userName, computerName);
}
Catatan
Mekanisme untuk status bertahan ini tidak ditujukan untuk data dalam jumlah besar, karena semua yang Anda masukkan ke state
dalam properti atau Clients.Caller
dua kali lipat dengan setiap pemanggilan metode. Ini berguna untuk item yang lebih kecil seperti nama pengguna atau penghitung.
Di VB.NET atau di hub yang sangat ditik, objek status penelepon tidak dapat diakses melalui Clients.Caller
; sebagai gantinya, gunakan Clients.CallerState
(diperkenalkan di SignalR 2.1):
Menggunakan CallerState di C#
public async Task NewContosoChatMessage(string data)
{
string userName = Clients.CallerState.userName;
string computerName = Clients.CallerState.computerName;
await Clients.Others.addContosoChatMessageToPage(data, userName, computerName);
}
Menggunakan CallerState di Visual Basic
Public Async Function NewContosoChatMessage(message As String) As Task
Dim userName As String = Clients.CallerState.userName
Dim computerName As String = Clients.CallerState.computerName
Await Clients.Others.addContosoChatMessageToPage(message, userName, computerName)
End Sub
Cara menangani kesalahan di kelas Hub
Untuk menangani kesalahan yang terjadi dalam metode kelas Hub Anda, pertama-tama pastikan Anda "mengamati" pengecualian apa pun dari operasi asinkron (seperti memanggil metode klien) dengan menggunakan await
. Kemudian gunakan satu atau beberapa metode berikut:
Bungkus kode metode Anda di blok try-catch dan catat objek pengecualian. Untuk tujuan penelusuran kesalahan, Anda dapat mengirim pengecualian ke klien, tetapi untuk alasan keamanan mengirim informasi terperinci ke klien dalam produksi tidak disarankan.
Buat modul alur Hub yang menangani metode OnIncomingError . Contoh berikut menunjukkan modul alur yang mencatat kesalahan, diikuti dengan kode di Startup.cs yang menyuntikkan modul ke dalam alur Hub.
public class ErrorHandlingPipelineModule : HubPipelineModule { protected override void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext) { Debug.WriteLine("=> Exception " + exceptionContext.Error.Message); if (exceptionContext.Error.InnerException != null) { Debug.WriteLine("=> Inner Exception " + exceptionContext.Error.InnerException.Message); } base.OnIncomingError(exceptionContext, invokerContext); } }
public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule()); app.MapSignalR(); }
HubException
Gunakan kelas (diperkenalkan di SignalR 2). Kesalahan ini dapat dilemparkan dari pemanggilan hub apa pun.HubError
Konstruktor mengambil pesan string, dan objek untuk menyimpan data kesalahan tambahan. SignalR akan melakukan serialisasi otomatis pengecualian dan mengirimkannya ke klien, di mana ia akan digunakan untuk menolak atau gagal dalam pemanggilan metode hub.Sampel kode berikut menunjukkan cara melempar
HubException
selama pemanggilan Hub, dan cara menangani pengecualian pada klien JavaScript dan .NET.Kode server yang menunjukkan kelas HubException
public class MyHub : Hub { public async Task Send(string message) { if(message.Contains("<script>")) { throw new HubException("This message will flow to the client", new { user = Context.User.Identity.Name, message = message }); } await Clients.All.send(message); } }
Kode klien JavaScript yang menunjukkan respons terhadap pelemparan HubException di hub
myHub.server.send("<script>") .fail(function (e) { if (e.source === 'HubException') { console.log(e.message + ' : ' + e.data.user); } });
Kode klien .NET yang menunjukkan respons terhadap pelemparan HubException di hub
try { await myHub.Invoke("Send", "<script>"); } catch(HubException ex) { Console.WriteLine(ex.Message); }
Untuk informasi selengkapnya tentang modul alur Hub, lihat Cara menyesuaikan alur Hub nanti dalam topik ini.
Cara mengaktifkan pelacakan
Untuk mengaktifkan pelacakan sisi server, tambahkan elemen system.diagnostics ke file Web.config Anda, seperti yang ditunjukkan dalam contoh ini:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="SignalRSamples" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;" />
<add name="SignalRSamplesWithMARS" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;MultipleActiveResultSets=true;" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.diagnostics>
<sources>
<source name="SignalR.SqlMessageBus">
<listeners>
<add name="SignalR-Bus" />
</listeners>
</source>
<source name="SignalR.ServiceBusMessageBus">
<listeners>
<add name="SignalR-Bus" />
</listeners>
</source>
<source name="SignalR.ScaleoutMessageBus">
<listeners>
<add name="SignalR-Bus" />
</listeners>
</source>
<source name="SignalR.Transports.WebSocketTransport">
<listeners>
<add name="SignalR-Transports" />
</listeners>
</source>
<source name="SignalR.Transports.ServerSentEventsTransport">
<listeners>
<add name="SignalR-Transports" />
</listeners>
</source>
<source name="SignalR.Transports.ForeverFrameTransport">
<listeners>
<add name="SignalR-Transports" />
</listeners>
</source>
<source name="SignalR.Transports.LongPollingTransport">
<listeners>
<add name="SignalR-Transports" />
</listeners>
</source>
<source name="SignalR.Transports.TransportHeartBeat">
<listeners>
<add name="SignalR-Transports" />
</listeners>
</source>
</sources>
<switches>
<add name="SignalRSwitch" value="Verbose" />
</switches>
<sharedListeners>
<add name="SignalR-Transports"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="transports.log.txt" />
<add name="SignalR-Bus"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="bus.log.txt" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
Saat menjalankan aplikasi di Visual Studio, Anda dapat melihat log di jendela Output .
Cara memanggil metode klien dan mengelola grup dari luar kelas Hub
Untuk memanggil metode klien dari kelas yang berbeda dari kelas Hub Anda, dapatkan referensi ke objek konteks SignalR untuk Hub dan gunakan itu untuk memanggil metode pada klien atau mengelola grup.
Kelas sampel StockTicker
berikut mendapatkan objek konteks, menyimpannya dalam instans kelas, menyimpan instans kelas dalam properti statis, dan menggunakan konteks dari instans kelas singleton untuk memanggil updateStockPrice
metode pada klien yang terhubung ke Hub bernama StockTickerHub
.
// For the complete example, go to
// http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-aspnet-signalr
// This sample only shows code related to getting and using the SignalR context.
public class StockTicker
{
// Singleton instance
private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(
() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>()));
private IHubContext _context;
private StockTicker(IHubContext context)
{
_context = context;
}
// This method is invoked by a Timer object.
private void UpdateStockPrices(object state)
{
foreach (var stock in _stocks.Values)
{
if (TryUpdateStockPrice(stock))
{
_context.Clients.All.updateStockPrice(stock);
}
}
}
Jika Anda perlu menggunakan konteks beberapa kali dalam objek berumur panjang, dapatkan referensi sekali dan simpan daripada mendapatkannya lagi setiap kali. Mendapatkan konteks sekali memastikan bahwa SignalR mengirim pesan ke klien dalam urutan yang sama di mana metode Hub Anda membuat pemanggilan metode klien. Untuk tutorial yang menunjukkan cara menggunakan konteks SignalR untuk Hub, lihat Siaran Server dengan ASP.NET SignalR.
Memanggil metode klien
Anda dapat menentukan klien mana yang akan menerima RPC, tetapi Anda memiliki lebih sedikit opsi daripada saat Anda memanggil dari kelas Hub. Alasan untuk ini adalah bahwa konteksnya tidak terkait dengan panggilan tertentu dari klien, sehingga metode apa pun yang memerlukan pengetahuan tentang ID koneksi saat ini, seperti Clients.Others
, atau Clients.Caller
, atau Clients.OthersInGroup
, tidak tersedia. Opsi berikut tersedia:
Semua klien yang terhubung.
context.Clients.All.addContosoChatMessageToPage(name, message);
Klien tertentu yang diidentifikasi oleh ID koneksi.
context.Clients.Client(connectionID).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung kecuali klien yang ditentukan, diidentifikasi oleh ID koneksi.
context.Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung dalam grup tertentu.
context.Clients.Group(groupName).addContosoChatMessageToPage(name, message);
Semua klien yang terhubung dalam grup tertentu kecuali klien tertentu, yang diidentifikasi oleh ID koneksi.
Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
Jika Anda memanggil kelas non-Hub dari metode di kelas Hub, Anda dapat meneruskan ID koneksi saat ini dan menggunakannya dengan Clients.Client
, , Clients.AllExcept
atau Clients.Group
untuk mensimulasikan Clients.Caller
, , Clients.Others
atau Clients.OthersInGroup
. Dalam contoh berikut, MoveShapeHub
kelas meneruskan ID koneksi ke Broadcaster
kelas sehingga Broadcaster
kelas dapat mensimulasikan Clients.Others
.
// For the complete example, see
// http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20
// This sample only shows code that passes connection ID to the non-Hub class,
// in order to simulate Clients.Others.
public class MoveShapeHub : Hub
{
// Code not shown puts a singleton instance of Broadcaster in this variable.
private Broadcaster _broadcaster;
public void UpdateModel(ShapeModel clientModel)
{
clientModel.LastUpdatedBy = Context.ConnectionId;
// Update the shape model within our broadcaster
_broadcaster.UpdateShape(clientModel);
}
}
public class Broadcaster
{
public Broadcaster()
{
_hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
}
public void UpdateShape(ShapeModel clientModel)
{
_model = clientModel;
_modelUpdated = true;
}
// Called by a Timer object.
public void BroadcastShape(object state)
{
if (_modelUpdated)
{
_hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
_modelUpdated = false;
}
}
}
Mengelola keanggotaan grup
Untuk mengelola grup, Anda memiliki opsi yang sama seperti yang Anda lakukan di kelas Hub.
Menambahkan klien ke grup
context.Groups.Add(connectionID, groupName);
Menghapus klien dari grup
context.Groups.Remove(connectionID, groupName);
Cara menyesuaikan alur Hub
SignalR memungkinkan Anda untuk menyuntikkan kode Anda sendiri ke dalam alur Hub. Contoh berikut menunjukkan modul alur Hub kustom yang mencatat setiap panggilan metode masuk yang diterima dari klien dan panggilan metode keluar yang dipanggil pada klien:
public class LoggingPipelineModule : HubPipelineModule
{
protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context)
{
Debug.WriteLine("=> Invoking " + context.MethodDescriptor.Name + " on hub " + context.MethodDescriptor.Hub.Name);
return base.OnBeforeIncoming(context);
}
protected override bool OnBeforeOutgoing(IHubOutgoingInvokerContext context)
{
Debug.WriteLine("<= Invoking " + context.Invocation.Method + " on client hub " + context.Invocation.Hub);
return base.OnBeforeOutgoing(context);
}
}
Kode berikut dalam file Startup.cs mendaftarkan modul untuk dijalankan di alur Hub:
public void Configuration(IAppBuilder app)
{
GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());
app.MapSignalR();
}
Ada banyak metode berbeda yang dapat Anda ambil alih. Untuk daftar lengkapnya, lihat Metode HubPipelineModule.