ASP.NET Core SignalR .NET İstemcisi
ASP.NET Core SignalR .NET istemci kitaplığı, .NET uygulamalarından hub'larla SignalR iletişim kurmanızı sağlar.
Örnek kodu görüntüleme veya indirme (indirme)
Bu makaledeki kod örneği, ASP.NET Core SignalR .NET istemcisini kullanan bir WPF uygulamasıdır.
SignalR .NET istemci paketini yükleme
Microsoft.AspNetCore.SignalR. .NET istemcilerinin hub'lara SignalR bağlanması için istemci paketi gereklidir.
İstemci kitaplığını yüklemek için Paket Yöneticisi Konsolu penceresinde aşağıdaki komutu çalıştırın:
Install-Package Microsoft.AspNetCore.SignalR.Client
Hub'a bağlanma
Bağlantı kurmak için bir HubConnectionBuilder
oluşturun ve çağrısında bulunur Build
. Bağlantı oluşturulurken hub URL'si, protokol, aktarım türü, günlük düzeyi, üst bilgiler ve diğer seçenekler yapılandırılabilir. yöntemlerinden herhangi birini HubConnectionBuilder
içine Build
ekleyerek gerekli seçenekleri yapılandırın. ile StartAsync
bağlantıyı başlatın.
using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.AspNetCore.SignalR.Client;
namespace SignalRChatClient
{
public partial class MainWindow : Window
{
HubConnection connection;
public MainWindow()
{
InitializeComponent();
connection = new HubConnectionBuilder()
.WithUrl("http://localhost:53353/ChatHub")
.Build();
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
}
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
try
{
await connection.StartAsync();
messagesList.Items.Add("Connection started");
connectButton.IsEnabled = false;
sendButton.IsEnabled = true;
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
private async void sendButton_Click(object sender, RoutedEventArgs e)
{
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
}
}
Kayıp bağlantıyı işleme
Otomatik olarak yeniden bağlanma
, HubConnection üzerindeki HubConnectionBuilderyöntemi kullanılarak WithAutomaticReconnect
otomatik olarak yeniden bağlanacak şekilde yapılandırılabilir. Varsayılan olarak otomatik olarak yeniden bağlanmaz.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect()
.Build();
Herhangi bir parametre olmadan, WithAutomaticReconnect()
istemciyi her yeniden bağlanma girişimini denemeden önce sırasıyla 0, 2, 10 ve 30 saniye bekleyecek şekilde yapılandırarak başarısız olan dört denemeden sonra durdurulmasını sağlar.
Herhangi bir yeniden bağlanma girişimine başlamadan önce, HubConnection
duruma geçirilecek HubConnectionState.Reconnecting
ve olayı tetikleyecektir Reconnecting
. Bu, kullanıcıları bağlantının kaybolduğu konusunda uyarmak ve kullanıcı arabirimi öğelerini devre dışı bırakmak için bir fırsat sağlar. Etkileşimli olmayan uygulamalar iletileri kuyruğa alma veya bırakma işlemini başlatabilir.
connection.Reconnecting += error =>
{
Debug.Assert(connection.State == HubConnectionState.Reconnecting);
// Notify users the connection was lost and the client is reconnecting.
// Start queuing or dropping messages.
return Task.CompletedTask;
};
İstemci ilk dört denemesinde başarıyla yeniden bağlanırsa, HubConnection
duruma geri Connected
döner ve olayı başlatır Reconnected
. Bu, kullanıcılara bağlantının yeniden kuruldığını ve kuyruğa alınan iletilerin sırasının kaldırıldığını bildirme fırsatı sağlar.
Bağlantı sunucuda tamamen yeni göründüğünden, olay işleyicilerine Reconnected
yeni ConnectionId
bir sağlanacaktır.
Uyarı
Reconnected
anlaşması atlanacak şekilde yapılandırıldıysa olay işleyicisinin connectionId
HubConnection
parametresi null olur.
connection.Reconnected += connectionId =>
{
Debug.Assert(connection.State == HubConnectionState.Connected);
// Notify users the connection was reestablished.
// Start dequeuing messages queued while reconnecting if any.
return Task.CompletedTask;
};
WithAutomaticReconnect()
ilk başlatma hatalarını yeniden denemek için öğesini yapılandırmaz HubConnection
, bu nedenle başlatma hatalarının el ile işlenmesi gerekir:
public static async Task<bool> ConnectWithRetryAsync(HubConnection connection, CancellationToken token)
{
// Keep trying to until we can start or the token is canceled.
while (true)
{
try
{
await connection.StartAsync(token);
Debug.Assert(connection.State == HubConnectionState.Connected);
return true;
}
catch when (token.IsCancellationRequested)
{
return false;
}
catch
{
// Failed to connect, trying again in 5000 ms.
Debug.Assert(connection.State == HubConnectionState.Disconnected);
await Task.Delay(5000);
}
}
}
İstemci ilk dört denemesinde başarıyla yeniden bağlanamazsa, HubConnection
duruma geçirilip Disconnected
olayı tetikler Closed . Bu, bağlantıyı el ile yeniden başlatmayı deneme veya kullanıcılara bağlantının kalıcı olarak kaybolduğunu bildirme fırsatı sağlar.
connection.Closed += error =>
{
Debug.Assert(connection.State == HubConnectionState.Disconnected);
// Notify users the connection has been closed or manually try to restart the connection.
return Task.CompletedTask;
};
Bağlantıyı kesmeden veya yeniden bağlanma zamanlamasını değiştirmeden önce özel sayıda yeniden bağlanma girişimi yapılandırmak için, WithAutomaticReconnect
her yeniden bağlantı girişimine başlamadan önce beklenmesi gereken gecikmeyi milisaniye cinsinden gösteren bir sayı dizisini kabul eder.
HubConnection connection= new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
.Build();
// .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) yields the default behavior.
Yukarıdaki örnek, bağlantı kesildikten hemen sonra yeniden bağlanmayı başlatacak şekilde yapılandırılır HubConnection
. Bu, varsayılan yapılandırma için de geçerlidir.
İlk yeniden bağlanma girişimi başarısız olursa, ikinci yeniden bağlanma girişimi de varsayılan yapılandırmada olduğu gibi 2 saniye beklemek yerine hemen başlar.
İkinci yeniden bağlanma girişimi başarısız olursa, üçüncü yeniden bağlanma girişimi 10 saniye içinde başlar ve bu yeniden varsayılan yapılandırmaya benzer.
Daha sonra özel davranış, üçüncü yeniden bağlanma girişimi hatasından sonra durarak varsayılan davranıştan yeniden ayrılır. Varsayılan yapılandırmada 30 saniye içinde bir yeniden bağlanma girişimi daha olacaktır.
Otomatik yeniden bağlanma girişimlerinin zamanlaması ve sayısı üzerinde daha fazla denetime sahip olmak istiyorsanız, WithAutomaticReconnect
adlı NextRetryDelay
tek bir yöntemi olan arabirimi uygulayan IRetryPolicy
bir nesneyi kabul eder.
NextRetryDelay
türünde RetryContext
tek bir bağımsız değişken alır. üç RetryContext
özelliğe sahiptir: PreviousRetryCount
sırasıyla ElapsedTime
RetryReason
, long
ve olan , TimeSpan
ve Exception
. İlk yeniden bağlanma girişiminden önce hem hem de PreviousRetryCount
ElapsedTime
sıfır olur ve RetryReason
bağlantının kaybolmasına neden olan Özel Durum olur. Başarısız olan her yeniden deneme girişiminden sonra, PreviousRetryCount
bir artırılacak, ElapsedTime
şimdiye kadar yeniden bağlanmaya harcanan süreyi yansıtacak şekilde güncelleştirilecek ve RetryReason
son yeniden bağlanma girişiminin başarısız olmasına neden olan Özel Durum olacaktır.
NextRetryDelay
bir sonraki yeniden bağlanma girişiminden null
önce beklenmesi gereken süreyi veya yeniden bağlanmayı durdurması HubConnection
gerektiğini gösteren bir TimeSpan döndürmelidir.
public class RandomRetryPolicy : IRetryPolicy
{
private readonly Random _random = new Random();
public TimeSpan? NextRetryDelay(RetryContext retryContext)
{
// If we've been reconnecting for less than 60 seconds so far,
// wait between 0 and 10 seconds before the next reconnect attempt.
if (retryContext.ElapsedTime < TimeSpan.FromSeconds(60))
{
return TimeSpan.FromSeconds(_random.NextDouble() * 10);
}
else
{
// If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
return null;
}
}
}
HubConnection connection = new HubConnectionBuilder()
.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
.WithAutomaticReconnect(new RandomRetryPolicy())
.Build();
Alternatif olarak, el ile yeniden bağlanma bölümünde gösterildiği gibi istemcinizi el ile yeniden bağlayacak kod yazabilirsiniz.
El ile yeniden bağlanma
Uyarı
3.0'ın öncesinde için SignalR .NET istemcisi otomatik olarak yeniden bağlanmaz. İstemcinizi el ile yeniden bağlayacak kodu yazmanız gerekir.
Closed Kayıp bir bağlantıya yanıt vermek için olayını kullanın. Örneğin, yeniden bağlanmayı otomatikleştirmek isteyebilirsiniz.
OlayClosed
, zaman uyumsuz kodun kullanmadan async void
çalışmasına izin veren bir döndüren bir Task
temsilci gerektirir. Zaman uyumlu olarak çalışan bir Closed
olay işleyicisinde temsilci imzasını karşılamak için döndür:Task.CompletedTask
connection.Closed += (error) => {
// Do your close logic.
return Task.CompletedTask;
};
Zaman uyumsuz desteğin temel nedeni bağlantıyı yeniden başlatabilmenizdir. Bağlantı başlatmak zaman uyumsuz bir eylemdir.
Bağlantıyı yeniden başlatan bir Closed
işleyicide, aşağıdaki örnekte gösterildiği gibi sunucunun aşırı yüklenmesini önlemek için rastgele bir gecikme beklemeyi göz önünde bulundurun:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
İstemciden çağrı hub'ı yöntemleri
InvokeAsync
hub'da yöntemleri çağırır. Hub yöntemi adını ve hub yönteminde tanımlanan tüm bağımsız değişkenleri öğesine InvokeAsync
geçirin. SignalRzaman uyumsuz olduğundan, çağrıları yaparken ve await
kullanınasync
.
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
InvokeAsync
yöntemi, sunucu yöntemi döndürdüğünde tamamlanan bir Task
döndürür. Varsa dönüş değeri, sonucu Task
olarak sağlanır. sunucudaki yöntemi tarafından oluşturulan tüm özel durumlar hatalı Task
bir oluşturur. Sunucu yönteminin tamamlanmasını beklemek için söz dizimini ve try...catch
hataları işlemek için söz dizimini kullanınawait
.
yöntemi, SendAsync
ileti sunucuya gönderildiğinde tamamlanan bir Task
döndürür. Sunucu yöntemi tamamlanana kadar beklemediğinden döndürülen değer sağlanmadı Task
. İleti gönderilirken istemcide oluşturulan tüm özel durumlar hatalı Task
bir oluşturur. Gönderme hatalarını işlemek için ve try...catch
söz dizimlerini kullanınawait
.
Not
İstemciden hub yöntemlerini çağırmak yalnızca Azure SignalR Hizmeti Varsayılan modda kullanılırken desteklenir. Daha fazla bilgi için bkz . Sık Sorulan Sorular (azure-signalr GitHub deposu).
Hub'dan istemci yöntemlerini çağırma
Derlemeden sonra ancak bağlantıyı başlatmadan önce hub'ın çağıran connection.On
yöntemlerini tanımlayın.
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
içindeki connection.On
yukarıdaki kod, sunucu tarafı kodu yöntemini kullanarak SendAsync
çağırdığında çalıştırılır.
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user,message);
}
Not
Bağlantının hub tarafı kesin olarak türlenmiş mesajlaşmayı desteklese de istemcinin yöntem adıyla genel yöntemi HubConnection.On kullanarak kaydolması gerekir. Örnek için bkz . Host ASP.NET Core SignalR in background services.
Hata işleme ve günlüğe kaydetme
Try-catch deyimiyle hataları işleme. Exception
Bir hata oluştuktan sonra gerçekleştirecek uygun eylemi belirlemek için nesnesini inceleyin.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
Ek kaynaklar
ASP.NET Core