Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pustaka klien ASP.NET Core SignalR JavaScript memungkinkan pengembang untuk memanggil kode hub sisi SignalR server. Artikel ini menjelaskan cara menggunakan API untuk terhubung ke hub SignalR dan memanggil metode hub JavaScript serta metode klien.
Melihat atau mengunduh kode sampel (cara mengunduh)
SignalR Menginstal paket klien
SignalR Pustaka klien JavaScript dikirimkan sebagai paket npm. Ada beberapa cara untuk menginstal pustaka klien:
- Jalankan perintah
npmdi Visual Studio Package Manager Console. - Jalankan perintah
npmdi terminal terintegrasi di Visual Studio Code. - Referensikan salinan pustaka klien yang dihosting di Content Delivery Network (CDN).
- Gunakan LibMan dan instal file pustaka klien tertentu dari pustaka klien yang dihosting CDN.
Menginstal dengan npm
Jalankan perintah npm berikut di jendela Package Manager Console:
npm init -y
npm install @microsoft/signalr
npm menginstal konten paket di folder node_modules\@microsoft\signalr\dist\browser.
Selesaikan penyiapan:
Buat folder wwwroot/lib/signalr.
Salin file signalr.js ke folder wwwroot/lib/signalr .
Sekarang Anda dapat mereferensikan klien JavaScript yang diinstal SignalR di <script> elemen . Contohnya:
<script src="~/lib/signalr/signalr.js"></script>
Menggunakan CDN
Untuk menggunakan pustaka klien tanpa prasyarat npm, referensikan salinan pustaka klien yang dihosting CDN. Contohnya:
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
Contoh kode menentukan versi 6.0.1. Untuk mendapatkan versi pustaka klien terbaru, pilih salah satu CDN berikut:
Menginstal dengan LibMan
Pendekatan lain adalah menggunakan LibMan dan hanya menginstal file pustaka klien tertentu dari pustaka klien yang dihosting CDN. Misalnya, Anda hanya dapat menambahkan file JavaScript yang dikurangi ke proyek.
Untuk detail tentang pendekatan ini, lihat Menambahkan SignalR pustaka klien.
Sambungkan ke hub
Kode berikut membuat dan memulai koneksi. Nama hub tidak membedakan huruf besar/kecil:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.configureLogging(signalR.LogLevel.Information)
.build();
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
connection.onclose(async () => {
await start();
});
// Start the connection.
start();
Koneksi lintas-origin (CORS)
Biasanya, browser memuat koneksi dari domain yang sama dengan halaman yang diminta. Namun, ada kalanya koneksi ke domain lain diperlukan.
Untuk permintaan lintas domain, kode klien harus menggunakan URL absolut daripada URL relatif. Saat Anda menggunakan permintaan lintas domain, ubah .withUrl("/chathub") ke .withUrl("https://{App domain name}/chathub").
Untuk mencegah situs berbahaya membaca data sensitif dari situs lain, koneksi lintas asal dinonaktifkan secara bawaan. Untuk mengizinkan permintaan lintas origin, aktifkan CORS:
using SignalRChat.Hubs;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("https://example.com")
.AllowAnyHeader()
.WithMethods("GET", "POST")
.AllowCredentials();
});
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// UseCors must be called before MapHub.
app.UseCors();
app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");
app.Run();
Metode UseCors harus dipanggil sebelum memanggil MapHub metode .
Panggil metode hub dari klien
Klien JavaScript memanggil metode publik di hub melalui metode pemanggilanHubConnection. Metode invoke ini menerima:
- Nama metode hub.
- Argumen apa pun yang didefinisikan dalam metode hub.
Dalam kode yang disorot berikut, nama metode pada hub adalah SendMessage. Argumen kedua dan ketiga yang diteruskan ke invoke dipetakan ke argumen user dan message milik metode hub:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Memanggil metode hub dari klien hanya didukung jika menggunakan layanan Azure SignalR Service dalam mode Default. Untuk informasi selengkapnya, lihat Tanya Jawab Umum (repositori GitHub azure-signalr).
Metode invoke mengembalikan objek JavaScript Promise. Objek Promise diselesaikan dengan nilai pengembalian (jika ada) ketika metode pada server kembali. Jika metode pada server menghasilkan error, objek Promise ditolak dengan pesan error. Untuk menangani kasus ini, gunakan async dan await atau metode then dan catch milik objek Promise.
Klien JavaScript juga dapat memanggil metode publik pada hub melalui metode send dari HubConnection. Tidak seperti metode invoke, metode send tidak menunggu respons dari server. Metode send mengembalikan objek JavaScript Promise. Objek Promise diselesaikan ketika pesan dikirim ke server. Jika terjadi kesalahan saat mengirim pesan, objek ditolak Promise dengan pesan kesalahan. Untuk menangani kasus ini, gunakan async dan await atau metode then dan catch milik objek Promise.
Menggunakan sendtidak menunggu sampai server menerima pesan, sehingga tidak mungkin untuk mengembalikan data atau kesalahan dari server.
Panggil metode klien dari hub
Untuk menerima pesan dari hub, tentukan metode dengan menggunakan metode on dari HubConnection. Metode on ini menerima:
- Nama metode klien JavaScript.
- Argumen yang diteruskan oleh hub ke metode.
Dalam contoh berikut, nama metodenya adalah ReceiveMessage. Nama argumen adalah user dan message:
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
document.getElementById("messageList").appendChild(li);
});
Kode sebelumnya dalam connection.on berjalan ketika kode sisi server memanggilnya dengan menggunakan SendAsync metode :
using Microsoft.AspNetCore.SignalR;
namespace SignalRChat.Hubs;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
SignalR menentukan metode klien mana yang akan dipanggil dengan mencocokkan nama metode dan argumen yang ditentukan dalam SendAsync dan connection.on.
Praktik terbaik adalah memanggil metode mulai pada HubConnection setelah on. Pendekatan ini memastikan handler terdaftar sebelum pesan diterima.
Penanganan kesalahan dan pengelogan
Gunakan console.error untuk menghasilkan kesalahan ke konsol browser saat klien tidak dapat menyambungkan atau mengirim pesan:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Atur penelusuran log di sisi klien dengan meneruskan logger dan jenis kejadian yang akan dicatat saat koneksi dibuat. Pesan dicatat dengan tingkat log yang ditentukan dan yang lebih tinggi. Tingkat log yang tersedia adalah sebagai berikut:
| Tingkat log | Data yang dicatat | Deskripsi |
|---|---|---|
signalR.LogLevel.Error |
Pesan-pesan Kesalahan | Hanya mencatat pesan Error. |
signalR.LogLevel.Warning |
Pesan peringatan tentang potensi kesalahan | Mencatat pesan Warning dan Error. |
signalR.LogLevel.Information |
Pesan status tanpa kesalahan | Mencatat pesan Information, Warning, dan Error. |
signalR.LogLevel.Trace |
Pesan pelacakan | Mencatat semuanya, termasuk data yang diangkut antara hub dan klien. |
Gunakan metode configureLogging di HubConnectionBuilder untuk mengonfigurasi tingkat log. Pesan dicatat ke konsol browser:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.configureLogging(signalR.LogLevel.Information)
.build();
Menyambungkan kembali klien
Untuk terhubung kembali dengan klien, Anda dapat menyiapkan koneksi ulang otomatis atau mengonfigurasi koneksi secara manual.
Menyambungkan ulang secara otomatis
Klien JavaScript untuk SignalR dapat dikonfigurasi untuk terhubung kembali secara otomatis dengan menggunakan metode WithAutomaticReconnect di HubConnectionBuilder. Ini tidak akan tersambung kembali secara otomatis secara bawaan.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withAutomaticReconnect()
.build();
Tanpa parameter apa pun, WithAutomaticReconnect mengonfigurasi klien untuk masing-masing menunggu 0, 2, 10, dan 30 detik sebelum mencoba setiap upaya koneksi ulang. Setelah empat upaya gagal, ia berhenti mencoba menyambungkan kembali.
Sebelum memulai koneksi ulang, :HubConnection
- Beralih ke status HubConnectionState.Reconnecting dan memicu callback-nya
onreconnecting. - Tidak beralih ke status
Disconnectedatau memicu callbackonclose-nya seperti padaHubConnectionyang tidak dikonfigurasi untuk menyambung ulang secara otomatis.
Pendekatan koneksi ulang memberikan kesempatan untuk memperingatkan pengguna bahwa koneksi hilang dan untuk menonaktifkan elemen UI.
connection.onreconnecting(error => {
console.assert(connection.state === signalR.HubConnectionState.Reconnecting);
document.getElementById("messageInput").disabled = true;
const li = document.createElement("li");
li.textContent = `Connection lost due to error "${error}". Reconnecting.`;
document.getElementById("messageList").appendChild(li);
});
Jika klien berhasil terhubung kembali dalam empat upaya pertamanya, HubConnection beralih kembali ke status Connected dan memicu callback onreconnected-nya. Pendekatan ini memberikan kesempatan untuk memberi tahu pengguna bahwa koneksi kini telah tersambung kembali.
Karena koneksi tersebut terlihat sebagai koneksi yang benar-benar baru oleh server, connectionId baru diberikan ke callback onreconnected.
Parameter connectionId dari callback onreconnected adalah tidak terdefinisi jika HubConnection dikonfigurasi untuk melewati negosiasi.
connection.onreconnected(connectionId => {
console.assert(connection.state === signalR.HubConnectionState.Connected);
document.getElementById("messageInput").disabled = false;
const li = document.createElement("li");
li.textContent = `Connection reestablished. Connected with connectionId "${connectionId}".`;
document.getElementById("messageList").appendChild(li);
});
withAutomaticReconnect tidak mengonfigurasi HubConnection untuk mencoba lagi saat kegagalan awal terjadi, jadi kegagalan saat memulai perlu ditangani secara manual:
async function start() {
try {
await connection.start();
console.assert(connection.state === signalR.HubConnectionState.Connected);
console.log("SignalR Connected.");
} catch (err) {
console.assert(connection.state === signalR.HubConnectionState.Disconnected);
console.log(err);
setTimeout(() => start(), 5000);
}
};
Jika klien tidak berhasil tersambung kembali dalam empat percobaan pertamanya, HubConnection beralih ke status Disconnected dan memicu callback onclose. Pendekatan ini memberikan kesempatan untuk memberi tahu pengguna bahwa koneksi hilang secara permanen dan mencoba me-refresh halaman:
connection.onclose(error => {
console.assert(connection.state === signalR.HubConnectionState.Disconnected);
document.getElementById("messageInput").disabled = true;
const li = document.createElement("li");
li.textContent = `Connection closed due to error "${error}". Try refreshing this page to restart the connection.`;
document.getElementById("messageList").appendChild(li);
});
Untuk mengonfigurasi jumlah kustom upaya koneksi ulang sebelum memutuskan sambungan atau mengubah waktu koneksi ulang, withAutomaticReconnect menerima array angka yang mewakili penundaan dalam milidetik untuk menunggu sebelum memulai setiap upaya koneksi ulang.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withAutomaticReconnect([0, 0, 10000])
.build();
// .withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior
Contoh sebelumnya mengonfigurasi HubConnection untuk mulai mencoba menyambungkan kembali segera setelah koneksi hilang. Konfigurasi default juga menunggu nol (0) detik untuk mencoba menyambungkan kembali.
Jika upaya koneksi ulang pertama gagal, upaya koneksi ulang kedua juga segera dimulai alih-alih menunggu 2 detik seperti yang didefinisikan dalam konfigurasi default.
Jika upaya koneksi ulang kedua gagal, upaya koneksi ulang ketiga dimulai dalam 10 detik, yang merupakan perilaku yang sama yang ditentukan dalam konfigurasi default.
Waktu koneksi ulang yang dikonfigurasi berbeda dari perilaku default dengan berhenti setelah kegagalan upaya koneksi ulang ketiga. Dalam konfigurasi default, satu lagi upaya koneksi ulang dilakukan setelah 30 detik lagi.
Untuk kontrol lebih besar atas waktu dan jumlah upaya koneksi ulang otomatis, withAutomaticReconnect menerima objek yang mengimplementasikan IRetryPolicy antarmuka, yang memiliki satu metode bernama nextRetryDelayInMilliseconds.
nextRetryDelayInMilliseconds mengambil satu argumen dengan jenis RetryContext. memiliki RetryContext tiga properti: previousRetryCount (jenis number), elapsedMilliseconds (jenis number), dan retryReason (jenis Error).
Sebelum upaya koneksi ulang pertama,
previousRetryCountdanelapsedMillisecondskeduanya nol (0), danretryReasonmerupakan Kesalahan yang menyebabkan koneksi yang hilang.Setelah setiap upaya percobaan ulang yang gagal,
previousRetryCountbertambah satu,elapsedMillisecondsdiperbarui untuk mencerminkan jumlah waktu yang telah dihabiskan untuk menyambung ulang sejauh ini dalam milidetik, danretryReasonadalah galat yang menyebabkan percobaan penyambungan ulang terakhir gagal.
nextRetryDelayInMilliseconds harus mengembalikan angka yang menunjukkan jumlah milidetik untuk menunggu sebelum upaya koneksi ulang berikutnya atau null jika HubConnection harus berhenti menyambungkan kembali.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: retryContext => {
if (retryContext.elapsedMilliseconds < 60000) {
// If we've been reconnecting for less than 60 seconds so far,
// wait between 0 and 10 seconds before the next reconnect attempt.
return Math.random() * 10000;
} else {
// If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
return null;
}
}
})
.build();
Atau, Anda dapat menulis kode untuk menyambungkan kembali klien secara manual, seperti yang ditunjukkan di bagian berikutnya.
Menyambungkan ulang secara manual
Kode berikut menunjukkan pendekatan koneksi ulang manual yang khas:
Untuk memulai koneksi, buat fungsi. Dalam hal ini, fungsi
start.startPanggil fungsi di penanganan aktivitas koneksionclose.
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
connection.onclose(async () => {
await start();
});
Implementasi di lingkungan produksi biasanya menggunakan back-off eksponensial atau mencoba ulang sebanyak jumlah yang ditentukan.
Tab tidur peramban
Beberapa browser memiliki fitur pembeku tab atau tidur tab yang mengurangi penggunaan sumber daya komputer untuk tab yang tidak aktif. Namun, fungsionalitas ini dapat menyebabkan koneksi SignalR tertutup dan menimbulkan pengalaman pengguna yang tidak diinginkan.
Browser menerapkan heuristik untuk menentukan apakah tab harus ditidur, seperti:
- Memutar audio
- Memegang kunci web
- Menahan
IndexedDBkunci - Tersambung ke perangkat USB
- Menangkap video atau audio
- Sedang dicerminkan
- Menangkap jendela atau tampilan
Heuristik dapat berubah dari waktu ke waktu dan juga berbeda di seluruh browser. Periksa matriks dukungan dan cari tahu metode apa yang paling sesuai untuk skenario Anda.
Untuk menghindari tidurnya aplikasi, aplikasi harus memicu salah satu heuristik yang digunakan browser.
Contoh kode berikut menunjukkan cara menggunakan Web Lock untuk menjaga tab tetap terjaga dan menghindari penutupan koneksi yang tidak terduga:
var lockResolver;
if (navigator && navigator.locks && navigator.locks.request) {
const promise = new Promise((res) => {
lockResolver = res;
});
navigator.locks.request('unique_lock_name', { mode: "shared" }, () => {
return promise;
});
}
Dalam kode sebelumnya:
- Web Locks masih eksperimental. Pemeriksaan kondisional mengonfirmasi bahwa browser mendukung Kunci Web.
- Resolver promise JavaScript (
lockResolver) disimpan agar kunci dapat dilepaskan saat tab boleh masuk ke mode tidur. - Ketika koneksi ditutup, kunci dilepaskan dengan memanggil
lockResolver(). Saat kunci dilepaskan, tab diizinkan masuk mode tidur.
Konten terkait
Oleh Rachel Appel
Pustaka klien ASP.NET Core SignalR JavaScript memungkinkan pengembang untuk memanggil kode hub sisi server.
Melihat atau mengunduh kode sampel (cara mengunduh)
SignalR Menginstal paket klien
SignalR Pustaka klien JavaScript dikirimkan sebagai paket npm. Bagian berikut menguraikan berbagai cara untuk menginstal pustaka klien.
Menginstal dengan npm
Untuk Visual Studio, jalankan perintah berikut dari Package Manager Console saat berada di folder akar. Untuk Visual Studio Code, jalankan perintah berikut dari Terminal Terintegrasi.
npm init -y
npm install @microsoft/signalr
npm menginstal konten paket di folder node_modules\@microsoft\signalr\dist\browser. Buat folder baru bernama
Rujuk klien JavaScript SignalR di elemen <script>. Contohnya:
<script src="~/lib/signalr/signalr.js"></script>
Menggunakan Content Delivery Network (CDN)
Untuk menggunakan pustaka klien tanpa prasyarat npm, referensikan salinan pustaka klien yang dihosting CDN. Contohnya:
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.js"></script>
Pustaka klien tersedia pada CDN berikut:
Menginstal dengan LibMan
LibMan dapat digunakan untuk menginstal file pustaka klien tertentu dari pustaka klien yang dihosting CDN. Misalnya, hanya tambahkan file JavaScript yang dikurangi ke proyek. Untuk detail selengkapnya tentang pendekatan tersebut, lihat Menambahkan SignalR pustaka klien.
Sambungkan ke hub
Kode berikut membuat dan memulai koneksi. Nama hub tidak membedakan huruf besar/kecil:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.configureLogging(signalR.LogLevel.Information)
.build();
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
connection.onclose(async () => {
await start();
});
// Start the connection.
start();
Koneksi lintas asal
Biasanya, browser memuat koneksi dari domain yang sama dengan halaman yang diminta. Namun, ada kalanya koneksi ke domain lain diperlukan.
Important
Kode klien harus menggunakan URL absolut alih-alih URL relatif. Ubah .withUrl("/chathub") ke .withUrl("https://myappurl/chathub").
Untuk mencegah situs berbahaya membaca data sensitif dari situs lain, koneksi antarasal dinonaktifkan secara bawaan. Untuk mengizinkan permintaan lintas asal, aktifkan di kelas Startup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SignalRChat.Hubs;
namespace SignalRChat
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.WithOrigins("https://example.com")
.AllowCredentials();
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chathub");
});
}
}
}
Metode hub panggilan dari klien
Klien JavaScript memanggil metode publik di hub melalui metode pemanggilanHubConnection. Metode invoke menerima:
- Nama metode hub.
- Argumen apa pun yang didefinisikan dalam metode hub.
Dalam contoh berikut, nama metode pada hub adalah SendMessage. Argumen kedua dan ketiga yang diteruskan ke invoke dipetakan ke argumen user dan message milik metode hub:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Note
Memanggil metode hub dari klien hanya didukung saat menggunakan Layanan Azure SignalR dalam mode Default. Untuk informasi selengkapnya, lihat Tanya Jawab Umum (repositori GitHub azure-signalr).
Metode invoke mengembalikan JavaScript Promise.
Promise akan terselesaikan dengan nilai yang dikembalikan (jika ada) saat metode di server mengembalikan hasil. Jika metode pada server menghasilkan error, Promise akan ditolak dengan pesan kesalahan. Gunakan async dan await atau Promisemetode then dan catch untuk menangani kasus ini.
Klien JavaScript juga dapat memanggil metode publik pada hub melalui metode send dari HubConnection. Tidak seperti metode invoke, metode send tidak menunggu respons dari server. Metode send mengembalikan JavaScript Promise.
Promise diselesaikan ketika pesan telah dikirim ke server. Jika terjadi kesalahan saat mengirim pesan, Promise ditolak dengan pesan kesalahan. Gunakan async dan await atau Promisemetode then dan catch untuk menangani kasus ini.
Note
Penggunaan send tidak menunggu hingga server menerima pesan. Akibatnya, tidak dimungkinkan untuk mengembalikan data atau kesalahan dari server.
Panggil metode klien dari hub
Untuk menerima pesan dari hub, tentukan metode menggunakan metode on dari HubConnection.
- Nama metode klien JavaScript.
- Argumen yang diteruskan oleh hub ke metode.
Dalam contoh berikut, nama metodenya adalah ReceiveMessage. Nama argumen adalah user dan message:
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
document.getElementById("messageList").appendChild(li);
});
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);
}
SignalR menentukan metode klien mana yang akan dipanggil dengan mencocokkan nama metode dan argumen yang ditentukan dalam SendAsync dan connection.on.
Note
Sebagai praktik terbaik, panggil metode mulai pada HubConnection setelah on. Melakukannya memastikan handler Anda terdaftar sebelum pesan diterima.
Penanganan kesalahan dan pengelogan
Gunakan try dan catch dengan async dan await, atau metode catch milik Promise untuk menangani error sisi klien. Gunakan console.error untuk menghasilkan kesalahan ke konsol browser:
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Atur penelusuran log di sisi klien dengan meneruskan logger dan jenis kejadian yang akan dicatat saat koneksi dibuat. Pesan dicatat dengan tingkat log yang ditentukan dan yang lebih tinggi. Tingkat log yang tersedia adalah sebagai berikut:
-
signalR.LogLevel.Error: Pesan kesalahan. Hanya mencatat pesanError. -
signalR.LogLevel.Warning: Pesan peringatan tentang potensi kesalahan. LogWarning, dan pesanError. -
signalR.LogLevel.Information: Pesan status tanpa kesalahan. Mencatat pesanInformation,Warning, danError. -
signalR.LogLevel.Trace: Pesan pelacakan. Mencatat semuanya, termasuk data yang diangkut antara hub dan klien.
Gunakan metode configureLogging di HubConnectionBuilder untuk mengonfigurasi tingkat log. Pesan dicatat ke konsol browser:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.configureLogging(signalR.LogLevel.Information)
.build();
Menyambungkan kembali klien
Menyambungkan ulang secara otomatis
Klien JavaScript untuk SignalR dapat dikonfigurasi untuk terhubung kembali secara otomatis menggunakan withAutomaticReconnect metode di HubConnectionBuilder. Ini tidak akan secara otomatis terhubung kembali secara default.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/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 apa pun, HubConnection akan terlebih dahulu beralih ke status HubConnectionState.Reconnecting dan memanggil callback onreconnecting-nya, alih-alih beralih ke status Disconnected dan memanggil callback onclose-nya seperti HubConnection yang tidak dikonfigurasi untuk koneksi ulang otomatis. Ini memberikan kesempatan untuk memperingatkan pengguna bahwa koneksi telah hilang dan untuk menonaktifkan elemen UI.
connection.onreconnecting(error => {
console.assert(connection.state === signalR.HubConnectionState.Reconnecting);
document.getElementById("messageInput").disabled = true;
const li = document.createElement("li");
li.textContent = `Connection lost due to error "${error}". Reconnecting.`;
document.getElementById("messageList").appendChild(li);
});
Jika klien berhasil terhubung kembali dalam empat upaya pertamanya, HubConnection akan beralih kembali ke status Connected dan memicu callback onreconnected-nya. Hal ini memberi kesempatan untuk memberi tahu pengguna bahwa koneksi telah tersambung kembali.
Karena koneksi tersebut dianggap sebagai koneksi yang sepenuhnya baru oleh server, connectionId baru akan diberikan ke callback onreconnected.
Warning
Parameter onreconnected panggilan balik connectionId tidak akan ditentukan jika HubConnection dikonfigurasi untuk melewati negosiasi.
connection.onreconnected(connectionId => {
console.assert(connection.state === signalR.HubConnectionState.Connected);
document.getElementById("messageInput").disabled = false;
const li = document.createElement("li");
li.textContent = `Connection reestablished. Connected with connectionId "${connectionId}".`;
document.getElementById("messageList").appendChild(li);
});
withAutomaticReconnect() tidak akan mengonfigurasi HubConnection untuk mencoba kembali saat startup awal gagal, jadi kegagalan startup harus ditangani secara manual:
async function start() {
try {
await connection.start();
console.assert(connection.state === signalR.HubConnectionState.Connected);
console.log("SignalR Connected.");
} catch (err) {
console.assert(connection.state === signalR.HubConnectionState.Disconnected);
console.log(err);
setTimeout(() => start(), 5000);
}
};
Jika klien tidak berhasil tersambung kembali dalam empat percobaan pertamanya, HubConnection akan beralih ke status Disconnected dan memicu panggilan balik onclose-nya. Ini memberikan kesempatan untuk memberi tahu pengguna bahwa koneksi telah hilang secara permanen dan merekomendasikan penyegaran halaman:
connection.onclose(error => {
console.assert(connection.state === signalR.HubConnectionState.Disconnected);
document.getElementById("messageInput").disabled = true;
const li = document.createElement("li");
li.textContent = `Connection closed due to error "${error}". Try refreshing this page to restart the connection.`;
document.getElementById("messageList").appendChild(li);
});
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.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withAutomaticReconnect([0, 0, 10000])
.build();
// .withAutomaticReconnect([0, 2000, 10000, 30000]) 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 menyimpang lagi dari perilaku default dengan berhenti setelah kegagalan upaya koneksi ulang ketiga alih-alih mencoba satu lagi upaya koneksi ulang dalam 30 detik lain seperti dalam konfigurasi default.
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 nextRetryDelayInMilliseconds.
nextRetryDelayInMilliseconds mengambil satu argumen dengan jenis RetryContext.
RetryContext memiliki tiga properti: previousRetryCount, elapsedMilliseconds, dan retryReason yang masing-masing berupa number, number, dan Error. Sebelum upaya penyambungan ulang pertama, previousRetryCount dan elapsedMilliseconds akan bernilai nol, dan retryReason akan menjadi error yang menyebabkan koneksi terputus. Setelah setiap upaya coba lagi yang gagal, previousRetryCount akan bertambah satu, elapsedMilliseconds akan diperbarui untuk mencerminkan jumlah waktu yang dihabiskan untuk menyambungkan kembali sejauh ini dalam milidetik, dan retryReason akan menjadi Kesalahan yang menyebabkan upaya koneksi ulang terakhir gagal.
nextRetryDelayInMilliseconds harus mengembalikan angka yang menunjukkan jumlah milidetik untuk menunggu sebelum upaya koneksi ulang berikutnya atau null jika HubConnection harus berhenti menyambungkan kembali.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withAutomaticReconnect({
nextRetryDelayInMilliseconds: retryContext => {
if (retryContext.elapsedMilliseconds < 60000) {
// If we've been reconnecting for less than 60 seconds so far,
// wait between 0 and 10 seconds before the next reconnect attempt.
return Math.random() * 10000;
} else {
// If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
return null;
}
}
})
.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
Kode berikut menunjukkan pendekatan koneksi ulang manual yang khas:
- Fungsi (dalam hal ini,
startfungsi) dibuat untuk memulai koneksi. -
startPanggil fungsi di penanganan aktivitas koneksionclose.
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
connection.onclose(async () => {
await start();
});
Implementasi di lingkungan produksi biasanya menggunakan back-off eksponensial atau mencoba ulang sebanyak jumlah yang ditentukan.
Tab tidur peramban
Beberapa browser memiliki fitur pembeku tab atau tidur untuk mengurangi penggunaan sumber daya komputer untuk tab yang tidak aktif. Ini dapat menyebabkan SignalR koneksi ditutup dan dapat mengakibatkan pengalaman pengguna yang tidak diinginkan. Browser menggunakan heuristik untuk mencari tahu apakah tab harus ditidur, seperti:
- Memutar audio
- Memegang kunci web
- Menahan
IndexedDBkunci - Tersambung ke perangkat USB
- Menangkap video atau audio
- Sedang dicerminkan
- Menangkap jendela atau tampilan
Note
Heuristik ini dapat berubah dari waktu ke waktu atau berbeda antara browser. Periksa matriks dukungan Anda dan cari tahu metode apa yang paling sesuai untuk skenario Anda.
Untuk menghindari tidurnya aplikasi, aplikasi harus memicu salah satu heuristik yang digunakan browser.
Contoh kode berikut menunjukkan cara menggunakan Kunci Web untuk menjaga tab tetap terjaga dan menghindari penutupan koneksi yang tidak terduga.
var lockResolver;
if (navigator && navigator.locks && navigator.locks.request) {
const promise = new Promise((res) => {
lockResolver = res;
});
navigator.locks.request('unique_lock_name', { mode: "shared" }, () => {
return promise;
});
}
Untuk contoh kode sebelumnya:
- Web Locks masih eksperimental. Pemeriksaan kondisional mengonfirmasi bahwa browser mendukung Kunci Web.
- Resolver promise (
lockResolver) disimpan agar kunci dapat dilepaskan ketika tab boleh memasuki mode tidur. - Saat menutup koneksi, kunci dilepaskan dengan memanggil
lockResolver(). Saat kunci dilepaskan, tab diizinkan masuk mode tidur.
Sumber daya tambahan
ASP.NET Core