ASP.NET Core SignalR .NET Istemcisi
ASP.NET Core SignalR .net istemci kitaplığı, .net uygulamalarından hub 'larla iletişim kurmanızı sağlar SignalR .
Örnek kodu görüntüleme veya indirme (nasıl indirileceği)
bu makaledeki kod örneği, ASP.NET Core .net istemcisini kullanan bir WPF uygulamasıdır SignalR .
SignalR.NET istemci paketini yükler
Microsoft. AspNetCore. SignalR . .Net istemcilerinin hub 'lara bağlanması için istemci paketi gereklidir SignalR .
istemci 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
bir hub 'a Bağlan
Bir bağlantı kurmak için bir HubConnectionBuilder ve çağrısı oluşturun Build . Hub URL 'SI, protokol, aktarım türü, günlük düzeyi, üst bilgiler ve diğer seçenekler bir bağlantı oluşturulurken yapılandırılabilir. Herhangi bir yöntemden herhangi birini ekleyerek gerekli seçenekleri yapılandırın HubConnectionBuilder Build . Bağlantısını ile başlatın StartAsync .
using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.AspNetCore.SignalR.Client;
namespace SignalRChatClient
{
public partial class MainWindow : Window
{
HubConnection connection;
public MainWindow()
{
InitializeComponent();
connection = new HubConnectionBuilder()
.WithUrl("http://localhost:53353/ChatHub")
.Build();
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
}
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
try
{
await connection.StartAsync();
messagesList.Items.Add("Connection started");
connectButton.IsEnabled = false;
sendButton.IsEnabled = true;
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
private async void sendButton_Click(object sender, RoutedEventArgs e)
{
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}
}
}
}
Kayıp bağlantıyı işle
Otomatik olarak yeniden bağlan
, HubConnection Üzerinde yöntemi kullanılarak otomatik olarak yeniden bağlanacak şekilde yapılandırılabilir WithAutomaticReconnect HubConnectionBuilder . 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() her yeniden bağlanma denemesini denemeden önce, dört başarısız denemeden sonra durdurulan istemciyi 0, 2, 10 ve 30 saniye bekleyecek şekilde yapılandırır.
Yeniden bağlanma girişimlerini başlatmadan önce, HubConnection HubConnectionState.Reconnecting durumuna geçer ve olayı harekete geçirebilir Reconnecting . Bu, kullanıcıların bağlantının kaybedildiği ve Kullanıcı arabirimi öğelerini devre dışı bırakan kullanıcıları uyarma fırsatı sağlar. Etkileşimli olmayan uygulamalar, iletileri sıraya alabilir veya bırakarak 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 deneme süresi içinde başarıyla yeniden bağlanırsa, HubConnection Connected duruma geçer ve olayı harekete geçirebilir Reconnected . Bu, kullanıcılara bağlantı yeniden kurulduğunda ve sıraya alınan tüm iletileri sıradan bildiren bir fırsat sağlar.
Bağlantı sunucuya tamamen yeni göründüğünden olay işleyicilerine yeni bir verilecek ConnectionId Reconnected .
Uyarı
ReconnectedOlay işleyicisinin connectionId parametresi, HubConnection anlaşmayı atlayacakşekilde yapılandırıldıysa 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() , HubConnection ilk başlatma başarısızlıklarını yeniden denemek üzere yapılandırmaz, 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 denemeden sonra başarıyla yeniden bağlanmazsa, HubConnection Disconnected durumuna geçer ve olayı harekete geçirebilir Closed . Bu, bağlantıyı el ile yeniden başlatmayı denemek veya bağlantıyı kalıcı olarak kaybettiğini bildirmek için bir 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ğlantı girişimi yapılandırmak için, her bir WithAutomaticReconnect yeniden bağlanma denemesine başlamadan önce beklenecek gecikme süresi temsil eden bir sayı dizisi 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, HubConnection bağlantı kaybolduktan hemen sonra yeniden bağlanmaya başlamak için öğesini yapılandırır. Bu, varsayılan yapılandırma için de geçerlidir.
İlk yeniden bağlantı girişimi başarısız olursa, ikinci yeniden bağlanma denemesi de varsayılan yapılandırmada olduğu gibi 2 saniye beklemek yerine hemen başlatılır.
İkinci yeniden bağlantı girişimi başarısız olursa, üçüncü yeniden bağlanma denemesi varsayılan yapılandırma gibi 10 saniye içinde başlar.
Özel davranış daha sonra, üçüncü yeniden bağlantı girişimi başarısızlığından sonra durarak varsayılan davranıştan daha sonra yeniden ayrılmış. Varsayılan yapılandırmada, 30 saniye içinde bir veya daha fazla yeniden bağlantı denemesi olur.
Otomatik yeniden bağlanma girişimlerinin zamanlaması ve sayısı üzerinde daha fazla denetime sahip olmak isterseniz, WithAutomaticReconnect IRetryPolicy adlı tek bir yöntemine sahip olan arabirimini uygulayan nesneyi kabul eder NextRetryDelay .
NextRetryDelay türünde tek bir bağımsız değişken alır RetryContext . ,, RetryContext Ve sırasıyla bir olan üç özelliğe sahiptir: PreviousRetryCount ElapsedTime ve RetryReason long TimeSpan Exception . İlk yeniden bağlanma denemesinden önce, PreviousRetryCount ve ElapsedTime sıfır olur ve RetryReason bağlantının kaybolmasına neden olan özel durum olacaktır. Her başarısız yeniden deneme denemesinden sonra, PreviousRetryCount Bu, ElapsedTime şimdiye kadar bir süre sonra yeniden bağlanılan süreyi yansıtacak şekilde güncelleştirilir ve RetryReason son yeniden bağlanma denemesinin başarısız olmasına neden olan özel durum olacaktır.
NextRetryDelay bir sonraki yeniden bağlanma girişiminden önce beklenecek süreyi temsil eden bir TimeSpan değeri veya bunun yeniden null HubConnection bağlanması durdurulmalıdır.
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ğlanmabölümünde gösterildiği gibi istemcinizi el ile yeniden bağlayacaksınız.
El ile yeniden bağlan
Uyarı
3,0 ' den önce, için .NET istemcisi SignalR otomatik olarak yeniden bağlanmaz. İstemcinizi el ile yeniden bağlayacaksınız kodu yazmanız gerekir.
ClosedKayıp bir bağlantıya yanıt vermek için olayını kullanın. Örneğin, yeniden bağlanmayı otomatik hale getirmek isteyebilirsiniz.
ClosedOlay, Task zaman uyumsuz kodun kullanılmadan çalışmasına izin veren, döndüren bir temsilci gerektirir async void . Zaman uyumlu olarak çalışan bir olay işleyicisinde temsilci imzasını karşılamak için Closed şunu döndürün Task.CompletedTask :
connection.Closed += (error) => {
// Do your close logic.
return Task.CompletedTask;
};
Zaman uyumsuz desteğin ana nedeni, bağlantıyı yeniden başlatabilmeniz için kullanılır. Bir bağlantının başlatılması zaman uyumsuz bir işlemdir.
ClosedBağlantıyı yeniden başlatan bir İşleyicide, aşağıdaki örnekte gösterildiği gibi, sunucunun aşırı yüklenmesini engellemek için bazı rastgele gecikme yapmayı düşünün:
connection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0,5) * 1000);
await connection.StartAsync();
};
İstemciden çağrı merkezi yöntemleri
InvokeAsync Hub 'daki yöntemleri çağırır. Hub yöntemi adını ve hub metodunda tanımlanan tüm bağımsız değişkenleri öğesine geçirin InvokeAsync . SignalR zaman uyumsuzdur, bu nedenle async await çağrıları yaparken ve kullanın.
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
InvokeAsyncYöntemi, Task sunucu yöntemi döndürüldüğünde tamamlanmış bir döndürür. Varsa dönüş değeri, sonucu olarak sağlanır Task . Sunucu üzerindeki yöntemi tarafından oluşturulan özel durumlar hatalı bir şekilde üretir Task . awaitSunucu yönteminin tamamlanmasını beklemek için sözdizimi kullanın ve try...catch hataları işlemek için söz dizimini kullanın.
SendAsyncYöntemi, Task ileti sunucuya gönderildiğinde tamamlanmış bir döndürür. Bu Task , sunucu yöntemi tamamlanana kadar beklemediğinden hiçbir dönüş değeri sağlanmaz. İletiyi gönderirken istemcide oluşturulan özel durumlar hatalı bir şekilde oluşur Task . await try...catch Gönderme hatalarını işlemek için ve sözdizimini kullanın.
Not
Hub yöntemlerinin bir istemciden çağrılması 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ğır
Hub connection.On 'ı derlemeden sonra, ancak bağlantıyı başlatmadan önce kullanarak çağıran yöntemleri tanımlayın.
connection.On<string, string>("ReceiveMessage", (user, message) =>
{
this.Dispatcher.Invoke(() =>
{
var newMessage = $"{user}: {message}";
messagesList.Items.Add(newMessage);
});
});
Yukarıdaki kod, connection.On sunucu tarafı kodu yöntemini kullanarak çağırdığında çalıştırılır SendAsync .
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user,message);
}
Not
Bağlantının Merkez tarafı kesin türü belirtilmiş mesajlaşmayı desteklese de istemci, metot adına sahip genel yöntemi kullanarak kaydolmalıdır HubConnection.On . Örnek için bkz. SignalRarka plan hizmetlerinde ana bilgisayar ASP.NET Core
Hata işleme ve günlüğe kaydetme
Try-catch ifadesiyle hataları işleyin. ExceptionBir hata oluştuktan sonra gerçekleştirilecek uygun eylemi öğrenmek için nesneyi inceleyin.
try
{
await connection.InvokeAsync("SendMessage",
userTextBox.Text, messageTextBox.Text);
}
catch (Exception ex)
{
messagesList.Items.Add(ex.Message);
}