Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tarafından Rachel Appel ve Kevin Griffin
Hubs API'si SignalR , bağlı istemcilerin sunucudaki yöntemleri çağırarak gerçek zamanlı iletişimi kolaylaştırmalarına olanak tanır. Sunucu, istemci tarafından çağrılan yöntemleri, istemci ise sunucu tarafından çağrılan yöntemleri tanımlar. SignalR ayrıca, SignalR Hub’ın aracılık ettiği istemciler arası dolaylı iletişimi de etkinleştirir. Bu yaklaşım tek tek istemciler, gruplar veya tüm bağlı istemcilere ileti göndermeye olanak tanır. SignalR gerçek zamanlı istemciden sunucuya ve sunucudan istemciye iletişimi mümkün kılmak için gereken her şeyi gerçekleştirir.
Bu makalede hub'ları yapılandırma, istemcilere ileti gönderme ve sunucuların istemcilerden gelen sonuçları işlemesine izin verme işlemleri açıklanmaktadır.
Hub'ları yapılandırın SignalR
SignalR hub'larının gerektirdiği hizmetleri, AddSignalR dosyasında yöntemini çağırarak kaydedin:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
SignalR dosyasında MapHub yöntemini çağırarak uç noktalarını yapılandırın:
app.MapRazorPages();
app.MapHub<ChatHub>("/Chat");
app.Run();
Note
ASP.NET Core SignalR sunucu tarafı derlemeleri artık .NET Core SDK ile yüklenir. Daha fazla bilgi için SignalR paylaşılan çerçevedeki derlemeler konusuna bakın.
Hub oluşturma ve kullanma
öğesinden Hubdevralan bir sınıf bildirerek bir hub oluşturun. İstemcilerden çağrılabilen hale getirmek için sınıfına yöntemler ekleyin public :
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Note
- Hub sınıfının bir özelliğinde durumu depolamayın. Her hub yöntemi çağrısı yeni bir hub örneğinde yürütülür.
- Bağımlılık ekleme yoluyla direkt bir hub örneği oluşturmayın. Uygulamanızın başka bir yerinden bir istemciye ileti göndermek için IHubContext kullanın.
- Asenkron yöntemlerin hub'ın hayatta kalmasına bağlı olduğu durumlarda
awaitkullanın. Örneğin,Clients.All.SendAsync(...)kullanmadanawaitgibi bir yöntemi çağırırsanız, çağrı başarısız olabilir ve hub yöntemi,SendAsynctamamlanmadan önce tamamlanabilir.
'Context' nesne özelliklerini ve yöntemlerini kullanma
Hub sınıfı, bağlantı hakkında bilgi içeren ve aşağıdaki özellikleri barındıran bir Context özelliği içerir.
| Property | Description |
|---|---|
| ConnectionId | Bağlantının SignalR tarafından atanan benzersiz kimliğini alır. Her bağlantı için bir bağlantı kimliği vardır. |
| UserIdentifier | Kullanıcı tanımlayıcısını alır. Varsayılan olarak, SignalR, kullanıcı tanımlayıcısı olarak bağlantıyla ilişkilendirilmiş ClaimTypes.NameIdentifier içindeki ClaimsPrincipal özelliğini kullanır. |
| User | Geçerli kullanıcıyla ilişkili olan ClaimsPrincipal öğesini alır. |
| Items | Bu bağlantı kapsamında veri paylaşmak için kullanılabilecek bir anahtar/değer koleksiyonu alır. Veriler bu koleksiyonda depolanabilir ve farklı hub yöntemi çağrıları arasında bağlantı için kalıcı olur. |
| Features | Bağlantıdaki kullanılabilen özelliklerin koleksiyonunu alır. Bu koleksiyon şu anda çoğu senaryoda gerekli olmadığından ayrıntılı belgeler henüz sağlanmamıştır. |
| ConnectionAborted | Bağlantı durdurulduğunda bunu bildiren bir CancellationToken alır. |
Hub.Context özelliği aşağıdaki yöntemleri de içerir:
| Method | Description |
|---|---|
| GetHttpContext |
HttpContext bağlantıyı döndürür veya bağlantı bir HTTP isteğiyle ilişkilendirilmemişse null döndürür. HTTP bağlantıları için, HTTP üst bilgileri ve sorgu dizeleri gibi bilgileri almak için bu yöntemi kullanın. |
| Abort | Bağlantıyı iptal eder. |
'İstemciler' nesne özelliklerini ve yöntemlerini kullanma
sınıfı, Hub sunucu ve istemci arasındaki iletişim için aşağıdaki özellikleri içeren bir Clients özellik içerir:
| Property | Description |
|---|---|
| All | Tüm bağlı istemciler üzerinde bir yöntemi çağırır. |
| Caller | İstemcide hub yöntemini çağıran bir yöntemi çağırır. |
| Others | Yöntemini çağıran istemci dışındaki tüm bağlı istemcilerde bir yöntemi çağırır. |
Hub.Clients özelliği aşağıdaki yöntemleri de içerir:
| Method | Description |
|---|---|
| AllExcept | Belirtilen bağlantılar dışında tüm bağlı istemcilerde bir yöntemi çağırır. |
| Client | Belirli bir bağlı istemcide bir yöntemi çağırır. |
| Clients | Belirli bağlı istemciler üzerinde bir yöntemi çağırır. |
| Group | Belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır. |
| GroupExcept | Belirtilen bağlantılar dışında belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır. |
| Groups | Birden çok bağlantı grubunda bir yöntemi çağırır. |
| OthersInGroup | Hub yöntemini çağıran istemci hariç olmak üzere bir bağlantı grubundaki bir yöntemi çağırır. |
| User | Belirli bir kullanıcıyla ilişkili tüm bağlantılarda bir yöntemi çağırır. |
| Users | Belirtilen kullanıcılarla ilişkili tüm bağlantılarda bir yöntemi çağırır. |
Her özellik veya yöntem, SendAsync yöntemine sahip bir nesne döndürür.
SendAsync yöntemi, çağrılacak olan istemci yönteminin adını ve herhangi bir parametreyi alır.
ve Client yöntemleri tarafından Caller döndürülen nesne, istemciden bir sonuç beklemek için kullanılabilecek bir InvokeAsyncyöntem de içerir.
İstemcilere ileti gönderme
Belirli istemcilere çağrı yapmak için nesnesinin Clients özelliklerini kullanın. Aşağıdaki örnekte üç hub yöntemi vardır:
- yöntemi,
SendMessageözelliğini kullanarakClients.Alltüm bağlı istemcilere bir ileti gönderir. -
SendMessageToCalleryöntemi,Clients.Callerözelliğini kullanarak çağırana bir ileti gönderir. - yöntemi,
SendMessageToGroupgruptakiSignalR Userstüm istemcilere bir ileti gönderir.
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
Kesin türemiş hub'lar kullanma
yöntemini kullanmanın SendAsync bir dezavantajı, çağrılacak istemci yöntemini belirtmek için bir dizeye bağlı olmasıdır. Yöntem adı yanlış yazılmışsa veya istemcide eksikse bu tasarım kodu çalışma zamanı hatalarına açık bırakır.
SendAsync yöntemini kullanmaya bir alternatif, Hub sınıfını Hub<T> ile kesin olarak türlendirmektir. Aşağıdaki örnekte, ChatHub istemci yöntemi, IChatClient adlı bir arabirime ayıklanır:
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Arabirim, önceki ChatHub örneğini güçlü biçimde türlendirilmiş hale getirmek için yeniden düzenlemede kullanılabilir:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
=> await Clients.All.ReceiveMessage(user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.ReceiveMessage(user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").ReceiveMessage(user, message);
}
kullanarak Hub<IChatClient> istemci yöntemlerinin derleme zamanı denetimini etkinleştirir. Bu yaklaşım yalnızca arabirimde tanımlanan yöntemlere erişim sağlayabildiği için dizelerin Hub<T> kullanılmasından kaynaklanan sorunları önler. Güçlü tür belirtimi yapılmış bir Hub<T> kullanmak, SendAsync yöntemini kullanma olanağını devre dışı bırakır.
Note
Sonek Async , yöntem adlarından çıkarılmamış.
.on('MyMethodAsync') ile tanımlanmış bir istemci yöntemi olmadığı sürece, MyMethodAsync adını kullanmayın.
İstemci sonuçlarını iste
sunucu, istemcilere çağrı yapmaya ek olarak bir istemciden sonuç isteyebilir. Bu senaryoda sunucu, ISingleClientProxy.InvokeAsync yöntemini kullanır ve istemci, .On işleyicisinden bir sonuç döndürür.
Api'yi sunucuda kullanmanın iki yolu vardır.
Bir Client(...) yöntemde, Caller özelliği üzerinde Clients veya Hub çağırabilirsiniz:
public class ChatHub : Hub
{
public async Task<string> WaitForMessage(string connectionId)
{
var message = await Clients.Client(connectionId).InvokeAsync<string>(
"GetMessage");
return message;
}
}
Ya da, Client(...) örneği üzerinde < çağrısı yapabilirsiniz:
async Task SomeMethod(IHubContext<MyHub> context)
{
string result = await context.Clients.Client(connectionID).InvokeAsync<string>(
"GetMessage");
}
Kesin olarak yazılan hub'lar, arabirim yöntemlerinden de değer döndürebilir:
public interface IClient
{
Task<string> GetMessage();
}
public class ChatHub : Hub<IClient>
{
public async Task<string> WaitForMessage(string connectionId)
{
string message = await Clients.Client(connectionId).GetMessage();
return message;
}
}
İstemciler, aşağıdaki bölümlerde gösterildiği gibi sonuçları .On(...) işleyicilerinde döndürür.
.NET istemcisi
hubConnection.On("GetMessage", async () =>
{
Console.WriteLine("Enter message:");
var message = await Console.In.ReadLineAsync();
return message;
});
TypeScript istemcisi
hubConnection.on("GetMessage", async () => {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("message");
}, 100);
});
return promise;
});
Java istemcisi
hubConnection.onWithResult("GetMessage", () -> {
return Single.just("message");
});
Hub yönteminin adını değiştirme
Varsayılan olarak, sunucu hub'ı yöntemi adı .NET yönteminin adıdır. Belirli bir yöntemin bu varsayılan davranışını değiştirmek için HubMethodName özniteliğini kullanın. İstemci, yöntemini çağırırken .NET yöntemi adı yerine bu adı kullanmalıdır:
[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
=> await Clients.User(user).SendAsync("ReceiveMessage", user, message);
Hub'a hizmet ekleme
Hub oluşturucuları, bağımlılık eklemeden alınan hizmetleri parametre olarak kabul edebilir ve bu, bir hub yönteminde kullanılmak üzere sınıftaki özelliklerde depolanabilir.
Farklı hub yöntemleri için veya kod yazmanın alternatif bir yolu olarak birden çok hizmet eklediğinizde, hub yöntemleri bağımlılık eklemeden gelen hizmetleri de kabul edebilir. Varsayılan olarak, hub yöntemi parametreleri incelenir ve mümkünse bağımlılık eklemeden çözümlenir.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message, IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Hizmetlerden gelen parametrelerin örtük çözümlemesi istenmiyorsa DisableImplicitFromServicesParameters sunucu seçeneğiyle davranışı devre dışı bırakabilirsiniz.
Hub yöntemlerinde bağımlılık eklemeden hangi parametrelerin çözümleneceğini açıkça belirtmek için DisableImplicitFromServicesParameters özelliğini kullanın. Bağımlılık ekleme aracılığıyla çözümlenmesi gereken hub yönteminin parametrelerinde, [FromServices] özniteliğini veya IFromServiceMetadata uygulayan özel bir özniteliği belirtin.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
services.AddSignalR(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message,
[FromServices] IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Note
Bu özellik, isteğe bağlı olarak bağımlılık ekleme yapılandırmalarında uygulanan öğesini kullanır IServiceProviderIsService. Uygulama bağımlılığı ekleme kapsayıcısı bu özelliği desteklemiyorsa, hub yöntemlerine hizmet eklenmesi desteklenmez.
Bağımlılık enjeksiyonunda anahtarlı hizmetler desteği
Anahtarlı hizmetler mekanizması, anahtarları kullanarak bağımlılık ekleme hizmetlerini kaydetmenize ve almanıza olanak tanır. Bir hizmet, kaydetmek için AddKeyedSingleton yöntemi çağrılarak bir anahtarla ilişkilendirilir. Alternatif olarak, AddKeyedScoped veya AddKeyedTransient yöntemlerinden birini çağırabilirsiniz.
[FromKeyedServices] özniteliğiyle anahtarı belirterek kayıtlı bir hizmete erişirsiniz. Aşağıdaki kodda anahtarlı hizmetlerin nasıl kullanılacağı gösterilmektedir:
using Microsoft.AspNetCore.SignalR;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
var app = builder.Build();
app.MapRazorPages();
app.MapHub<MyHub>("/myHub");
app.Run();
public interface ICache
{
object Get(string key);
}
public class BigCache : ICache
{
public object Get(string key) => $"Resolving {key} from big cache.";
}
public class SmallCache : ICache
{
public object Get(string key) => $"Resolving {key} from small cache.";
}
public class MyHub : Hub
{
public void SmallCacheMethod([FromKeyedServices("small")] ICache cache)
{
Console.WriteLine(cache.Get("signalr"));
}
public void BigCacheMethod([FromKeyedServices("big")] ICache cache)
{
Console.WriteLine(cache.Get("signalr"));
}
}
Bağlantı başına akış çağrılarını sınırlama
MaximumParallelInvocationsPerClient bir istemcinin, kuyruğa alınmadan önce paralel olarak çalıştırabileceği akışsız hub yöntemi çağrılarının sayısını belirler. Akış merkezi çağrıları için geçerli değildir. Akış çağrıları, uzun süre çalışan ve eşzamanlı olması beklendiğinden kasıtlı olarak dışlanır, bu nedenle istemci bu ayardan bağımsız olarak herhangi bir sayıda eşzamanlı akış başlatabilir.
Akış çağrılarında bağlantı başına sınırı zorlamak için, öğeleri vermeden önce sayacı artıran ve bir blokta azaltmayı sağlayan özel bir yardımcı kullanarak akışı hub yönteminin içine finally sarmalayın:
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
public class StreamingHub : Hub
{
private static readonly ConcurrentDictionary<string, int> _activeStreams = new();
private const int MaxConcurrentStreams = 2;
public IAsyncEnumerable<int> Counter(
int count,
int delay,
CancellationToken cancellationToken)
{
return WithLimit(Context.ConnectionId, GetCounter(count, delay, cancellationToken));
}
private async IAsyncEnumerable<int> GetCounter(
int count,
int delay,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
for (var i = 0; i < count; i++)
{
cancellationToken.ThrowIfCancellationRequested();
yield return i;
await Task.Delay(delay, cancellationToken);
}
}
private async IAsyncEnumerable<T> WithLimit(
string connectionId,
IAsyncEnumerable<T> stream,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var current = _activeStreams.AddOrUpdate(
connectionId,
addValue: 1,
updateValueFactory: (_, count) => count + 1);
if (current > MaxConcurrentStreams)
{
Decrement(connectionId);
throw new HubException(
$"The connection is limited to {MaxConcurrentStreams} concurrent streaming invocations.");
}
try
{
await foreach (var item in stream.WithCancellation(cancellationToken))
{
yield return item;
}
}
finally
{
Decrement(connectionId);
}
}
private static void Decrement(string connectionId)
{
while (_activeStreams.TryGetValue(connectionId, out var current))
{
if (current <= 1)
{
if (_activeStreams.TryRemove(new KeyValuePair<string, int>(connectionId, current)))
{
return;
}
}
else if (_activeStreams.TryUpdate(connectionId, current - 1, current))
{
return;
}
}
}
}
Önemli nokta, WithLimit'ın orijinal IAsyncEnumerable<T>'i sarması ve sayacı yalnızca ilk öğe üretilene kadar değil, akışın tüm yaşam süresi boyunca yüksek tutulmasıdır.
finally Blok yalnızca istemci akışı tüketmeyi bitirdiğinde, iptal ettiğinde veya bağlantı kesildiğinde çalışır.
Akış merkezi yöntemleriniz ChannelReader<T> yerine IAsyncEnumerable<T> döndürüyorsa, benzer bir sarmalayıcı kullanılabilir. Aynı _activeStreams sözlüğünü kullanmalıdır; böylece her iki akış türü de ayrı ayrı kendi bağımsız sayımını tutmak yerine bağlantı düzeyinde tek bir sınırı paylaşır.
Note
_activeStreams sözlüğü static olduğundan, tüm hub örnekleri arasında paylaşılır. DI ile yönetilen durumu tercih ediyorsanız, sözlüğün sahibi olan tek bir hizmeti kaydedin ve hub oluşturucusuna yerleştirin.
Bağlantıdaki olayları yönet
Hubs API, SignalR ve OnConnectedAsync bağlantılarını yönetmek ve izlemek için OnDisconnectedAsync sanal yöntemlerini sağlar. bir istemci hub'a OnConnectedAsync bağlandığında eylemleri gerçekleştirmek için sanal yöntemi geçersiz kılın; örneğin, bunu bir gruba ekleyin:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
İstemci bağlantısı kesildiğinde eylemleri gerçekleştirmek için OnDisconnectedAsync sanal yöntemi geçersiz kılın. İstemcinin bağlantısı kasıtlı olarak, örneğin connection.stop() çağrısı yoluyla kesilirse, exception parametresi null olarak ayarlanır. Ancak, ağ hatası gibi bir hata nedeniyle istemcinin bağlantısı kesilirse, exception parametre hatayı açıklayan bir özel durum içerir:
public override async Task OnDisconnectedAsync(Exception? exception)
{
await base.OnDisconnectedAsync(exception);
}
RemoveFromGroupAsync yönteminin, OnDisconnectedAsync yöntemi içinde çağrılması gerekmez çünkü bu otomatik olarak gerçekleştirilir.
Hatalarla başa çıkma
Hub yöntemlerinde oluşan özel durumlar, yöntemini çağıran istemciye gönderilir. JavaScript istemcisinde invoke yöntemi bir JavaScript 'Promise' nesnesi döndürür. İstemciler, döndürülen söze bir catch işleyici ekleyebilir ya da özel durumları işlemek için try/catch ile async/await kullanabilir.
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Bir hub özel durum oluştururken bağlantılar kapatılamaz. Varsayılan olarak, SignalR aşağıdaki örnekte gösterildiği gibi istemciye genel bir hata iletisi döndürür:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'SendMessage' on the server.
Beklenmeyen özel durumlar genellikle veritabanı bağlantısı başarısız olduğunda tetiklenen bir özel durumdaki veritabanı sunucusunun adı gibi hassas bilgiler içerir. Güvenlik önlemi olarak, SignalR bu ayrıntılı hata iletilerini varsayılan olarak kullanıma sunmaz. Özel durum ayrıntılarının neden gizlendiğini öğrenmek için bkz . ASP.NET Core'da SignalRgüvenlikle ilgili dikkat edilmesi gerekenler.
İstemciye olağanüstü bir koşul yayılması gerekiyorsa sınıfını HubException kullanın.
HubException bir hub yönteminde oluşturulursa, SignalRözel durum iletisinin tamamını değiştirilmemiş bir biçimde istemciye gönderir:
public Task ThrowException()
=> throw new HubException("This error will be sent to the client!");
Note
SignalR yalnızca özel durumun özelliğini istemciye gönderir Message . Özel durumdaki yığın izlemesi ve diğer özellikler istemci tarafından kullanılamaz.
İlgili içerik
Tarafından Rachel Appel ve Kevin Griffin
Hubs API'si SignalR , bağlı istemcilerin sunucudaki yöntemleri çağırarak gerçek zamanlı iletişimi kolaylaştırmalarına olanak tanır. Sunucu, istemci tarafından çağrılan yöntemleri, istemci ise sunucu tarafından çağrılan yöntemleri tanımlar. SignalR ayrıca, her zaman Hub tarafından aracılık edilen dolaylı istemciden istemciye iletişimi etkinleştirir ve iletilerin SignalR tek tek istemciler, gruplar veya tüm bağlı istemcilere gönderilmesine olanak tanır. SignalR gerçek zamanlı istemciden sunucuya ve sunucudan istemciye iletişimi mümkün kılmak için gereken her şeyi gerçekleştirir.
Hub'ları yapılandırın SignalR
Hub'ların SignalR için gereken hizmetleri kaydetmek amacıyla AddSignalR'da Program.cs çağrısını yapın.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
Uç noktaları yapılandırmak için SignalR öğesini ve aynı zamanda MapHub, Program.cs çağırın.
app.MapRazorPages();
app.MapHub<ChatHub>("/Chat");
app.Run();
Note
ASP.NET Core SignalR sunucu tarafı derlemeleri artık .NET Core SDK ile yüklenir. Daha fazla bilgi için SignalR paylaşılan çerçevedeki derlemeler konusuna bakın.
Hub oluşturma ve kullanma
öğesinden Hubdevralan bir sınıf bildirerek bir hub oluşturun. İstemcilerden çağrılabilen hale getirmek için sınıfına yöntemler ekleyin public :
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Note
- Hub sınıfının bir özelliğinde durumu depolamayın. Her hub yöntemi çağrısı yeni bir hub örneğinde yürütülür.
- Bağımlılık ekleme yoluyla direkt bir hub örneği oluşturmayın. Uygulamanızın başka bir yerinden bir istemciye ileti göndermek için kullanın
IHubContext. - Asenkron yöntemlerin hub'ın hayatta kalmasına bağlı olduğu durumlarda
awaitkullanın. Örneğin,Clients.All.SendAsync(...)olmadanawaitgibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
Hub sınıfı, bağlantı hakkında bilgi içeren ve aşağıdaki özellikleri barındıran bir Context özelliği içerir.
| Property | Description |
|---|---|
| ConnectionId | Bağlantının SignalR tarafından atanan benzersiz kimliğini alır. Her bağlantı için bir bağlantı kimliği vardır. |
| UserIdentifier | Kullanıcı tanımlayıcısını alır. Varsayılan olarak, SignalR, bağlantıyla ilişkilendirilmiş ClaimTypes.NameIdentifier'den ClaimsPrincipal'i kullanıcı tanımlayıcısı olarak kullanır. |
| User | Geçerli kullanıcıyla ilişkili olan ClaimsPrincipal öğesini alır. |
| Items | Bu bağlantı kapsamında veri paylaşmak için kullanılabilecek bir anahtar/değer koleksiyonu alır. Veriler bu koleksiyonda depolanabilir ve farklı hub yöntemi çağrıları arasında bağlantı için kalıcı olur. |
| Features | Bağlantıdaki kullanılabilen özelliklerin koleksiyonunu alır. Şimdilik bu koleksiyon çoğu senaryoda gerekli olmadığından henüz ayrıntılı olarak belgelenmemiştir. |
| ConnectionAborted | Bağlantı durdurulduğunda bunu bildiren bir CancellationToken alır. |
Hub.Context ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| GetHttpContext |
HttpContext bağlantıyı döndürür veya bağlantı bir HTTP isteğiyle ilişkilendirilmemişse null döndürür. HTTP bağlantıları için, HTTP üst bilgileri ve sorgu dizeleri gibi bilgileri almak için bu yöntemi kullanın. |
| Abort | Bağlantıyı iptal eder. |
İstemci nesnesi
sınıfı, Hub sunucu ve istemci arasındaki iletişim için aşağıdaki özellikleri içeren bir Clients özellik içerir:
| Property | Description |
|---|---|
| All | Tüm bağlı istemcilerde bir yöntemi çağırır |
| Caller | İstemcide hub yöntemini çağıran bir yöntemi çağırır |
| Others | Yöntemini çağıran istemci dışındaki tüm bağlı istemcilerde bir yöntemi çağırır |
Hub.Clients ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| AllExcept | Belirtilen bağlantılar dışında tüm bağlı istemcilerde bir yöntemi çağırır |
| Client | Belirli bir bağlı istemcide bir yöntemi çağırır |
| Clients | Belirli bağlı istemcilerde bir yöntemi çağırır |
| Group | Belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| GroupExcept | Belirtilen bağlantılar dışında belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| Groups | Birden çok bağlantı grubunda bir yöntemi çağırır |
| OthersInGroup | Hub yöntemini çağıran istemci hariç olmak üzere bir bağlantı grubundaki bir yöntemi çağırır |
| User | Belirli bir kullanıcıyla ilişkili tüm bağlantılarda bir yöntemi çağırır |
| Users | Belirtilen kullanıcılarla ilişkili tüm bağlantılarda bir yöntemi çağırır |
Yukarıdaki tablolardaki her özellik veya yöntem, bir SendAsync yöntemine sahip bir nesne döndürür.
SendAsync yöntemi, çağrılacak olan istemci yönteminin adını ve herhangi bir parametreyi alır.
ve Client yöntemleri tarafından Caller döndürülen nesne, istemciden bir sonuç beklemek için kullanılabilecek bir InvokeAsyncyöntem de içerir.
İstemcilere ileti gönderme
Belirli istemcilere çağrı yapmak için nesnesinin Clients özelliklerini kullanın. Aşağıdaki örnekte üç hub yöntemi vardır:
-
SendMessagekullanarakClients.Alltüm bağlı istemcilere bir ileti gönderir. -
SendMessageToCallerkullanarakClients.Callerçağırana bir ileti gönderir. -
SendMessageToGroupgruptakiSignalR Userstüm istemcilere bir ileti gönderir.
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
Kesin türemiş hub'lar
kullanmanın SendAsync bir dezavantajı, çağrılacak istemci yöntemini belirtmek için bir dizeye bağlı olmasıdır. Bu, yöntem adı yanlış yazılmışsa veya istemcide eksikse kodu çalışma zamanı hatalarına açık bırakır.
SendAsync kullanmak yerine, Hub sınıfını Hub<T> ile güçlü bir şekilde tip belirlemektir. Aşağıdaki örnekte, ChatHub istemci yöntemi, adlı IChatClient isimli bir arabirime çıkartılmıştır.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Bu arabirim, önceki ChatHub örneği kesin olarak yazılacak şekilde yeniden düzenleme amacıyla kullanılabilir:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
=> await Clients.All.ReceiveMessage(user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.ReceiveMessage(user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").ReceiveMessage(user, message);
}
kullanarak Hub<IChatClient> istemci yöntemlerinin derleme zamanı denetimini etkinleştirir. Bu, Hub<T> yalnızca arabirimde tanımlanan yöntemlere erişim sağlayabildiği için dizelerin kullanılmasından kaynaklanan sorunları önler. Kesin türde bir Hub<T> kullanmak, SendAsync işlevini devre dışı bırakır.
Note
Sonek Async , yöntem adlarından çıkarılmamış.
.on('MyMethodAsync') ile tanımlanmış bir istemci yöntemi olmadığı sürece, MyMethodAsync adını kullanmayın.
İstemci sonuçları
sunucu, istemcilere çağrı yapmaya ek olarak bir istemciden sonuç isteyebilir. Bunun için sunucunun ISingleClientProxy.InvokeAsync kullanması ve istemcinin .On işleyicisinden bir sonuç döndürmesi gerekir.
API'yi sunucuda kullanmanın iki yolu vardır; birincisi, bir Hub yönteminde Client(...) özelliği üzerinden Caller veya Clients çağrısı yapmaktır.
public class ChatHub : Hub
{
public async Task<string> WaitForMessage(string connectionId)
{
var message = await Clients.Client(connectionId).InvokeAsync<string>(
"GetMessage");
return message;
}
}
İkinci yol, Client(...) örneğinde IHubContext<T> çağrısı yapmaktır:
async Task SomeMethod(IHubContext<MyHub> context)
{
string result = await context.Clients.Client(connectionID).InvokeAsync<string>(
"GetMessage");
}
Kesin türe sahip hub'lar, arabirim yöntemlerinden de değer döndürebilir:
public interface IClient
{
Task<string> GetMessage();
}
public class ChatHub : Hub<IClient>
{
public async Task<string> WaitForMessage(string connectionId)
{
string message = await Clients.Client(connectionId).GetMessage();
return message;
}
}
İstemciler, aşağıda gösterildiği gibi .On(...) işleyicilerinde sonuçları geri döndürür.
.NET istemcisi
hubConnection.On("GetMessage", async () =>
{
Console.WriteLine("Enter message:");
var message = await Console.In.ReadLineAsync();
return message;
});
Typescript istemcisi
hubConnection.on("GetMessage", async () => {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("message");
}, 100);
});
return promise;
});
Java istemcisi
hubConnection.onWithResult("GetMessage", () -> {
return Single.just("message");
});
Hub yönteminin adını değiştirme
Varsayılan olarak, sunucu hub'ı yöntemi adı .NET yönteminin adıdır. Belirli bir yöntemin bu varsayılan davranışını değiştirmek için HubMethodName özniteliğini kullanın. İstemci, yöntemini çağırırken .NET yöntemi adı yerine bu adı kullanmalıdır:
[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
=> await Clients.User(user).SendAsync("ReceiveMessage", user, message);
Hub'a hizmet ekleme
Hub oluşturucuları, DI'den gelen hizmetleri parametre olarak kabul edebilir ve bu hizmetler bir hub yönteminde kullanılmak üzere sınıfındaki özelliklerde depolanabilir.
Farklı hub yöntemleri için veya kod yazmanın alternatif bir yolu olarak birden çok hizmet eklerken, hub yöntemleri DI'den gelen hizmetleri de kabul edebilir. Varsayılan olarak, hub yöntemi parametreleri mümkünse DI'den incelenir ve çözümlenir.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message, IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Hizmetlerden gelen parametrelerin örtük çözümlemesi istenmiyorsa DisableImplicitFromServicesParameters ile devre dışı bırakın.
Hub yöntemlerinde DI'den hangi parametrelerin çözüleceğini açıkça belirtmek için, DisableImplicitFromServicesParameters seçeneğini kullanın ve DI'den çözümlenmesi gereken hub yöntemi parametrelerinin parametrelerinde [FromServices] özniteliğini veya uygulayan özel bir öznitelik kullanın IFromServiceMetadata.
services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
services.AddSignalR(options =>
{
options.DisableImplicitFromServicesParameters = true;
});
// ...
public class ChatHub : Hub
{
public Task SendMessage(string user, string message,
[FromServices] IDatabaseService dbService)
{
var userName = dbService.GetUserName(user);
return Clients.All.SendAsync("ReceiveMessage", userName, message);
}
}
Note
Bu özellik, isteğe bağlı olarak DI uygulamaları tarafından uygulanan IServiceProviderIsService özelliğini kullanır. Uygulamanın DI kapsayıcısı bu özelliği desteklemiyorsa, hub yöntemlerine hizmet ekleme desteklenmez.
Bağlantıdaki olayları yönet
Hubs API, SignalR ve OnConnectedAsync bağlantılarını yönetmek ve izlemek için OnDisconnectedAsync sanal yöntemlerini sağlar. bir istemci hub'a OnConnectedAsync bağlandığında eylemleri gerçekleştirmek için sanal yöntemi geçersiz kılın; örneğin, bunu bir gruba ekleyin:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
İstemci bağlantısı kesildiğinde eylemleri gerçekleştirmek için OnDisconnectedAsync sanal yöntemi geçersiz kılın. İstemcinin bağlantısı kasıtlı olarak, örneğin connection.stop() çağrısı yoluyla kesilirse, exception parametresi null olarak ayarlanır. Ancak, ağ hatası gibi bir hata nedeniyle istemcinin bağlantısı kesilirse, exception parametre hatayı açıklayan bir özel durum içerir:
public override async Task OnDisconnectedAsync(Exception? exception)
{
await base.OnDisconnectedAsync(exception);
}
RemoveFromGroupAsync OnDisconnectedAsync çağrılması gerekmez, sizin için otomatik olarak işlenir.
Hatalarla başa çıkma
Hub yöntemlerinde oluşan özel durumlar, yöntemini çağıran istemciye gönderilir. JavaScript istemcisinde invoke yöntemi bir JavaScript Promisedöndürür. İstemciler, döndürülen söze bir catch işleyici ekleyebilir ya da özel durumları işlemek için try/catch ile async/await kullanabilir.
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Bir hub özel durum oluştururken bağlantılar kapatılamaz. Varsayılan olarak, SignalR aşağıdaki örnekte gösterildiği gibi istemciye genel bir hata iletisi döndürür:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'SendMessage' on the server.
Beklenmeyen özel durumlar genellikle veritabanı bağlantısı başarısız olduğunda tetiklenen bir özel durumdaki veritabanı sunucusunun adı gibi hassas bilgiler içerir. SignalR güvenlik önlemi olarak bu ayrıntılı hata iletilerini varsayılan olarak kullanıma sunmaz. Özel durum ayrıntılarının neden gizlendiğini öğrenmek için bkz . ASP.NET Core'da SignalRgüvenlikle ilgili dikkat edilmesi gerekenler.
İstemciye olağanüstü bir koşul yayılması gerekiyorsa sınıfını HubException kullanın.
HubException bir hub yönteminde oluşturulursa, SignalRözel durum iletisinin tamamını değiştirilmemiş olarak istemciye gönderir:
public Task ThrowException()
=> throw new HubException("This error will be sent to the client!");
Note
SignalR yalnızca özel durumun özelliğini istemciye gönderir Message . Özel durumdaki yığın izlemesi ve diğer özellikler istemci tarafından kullanılamaz.
Ek kaynaklar
Tarafından Rachel Appel ve Kevin Griffin
Hubs API'si SignalR , bağlı istemcilerin sunucudaki yöntemleri çağırarak gerçek zamanlı iletişimi kolaylaştırmalarına olanak tanır. Sunucu, istemci tarafından çağrılan yöntemleri, istemci ise sunucu tarafından çağrılan yöntemleri tanımlar. SignalR ayrıca, her zaman Hub tarafından aracılık edilen dolaylı istemciden istemciye iletişimi etkinleştirir ve iletilerin SignalR tek tek istemciler, gruplar veya tüm bağlı istemcilere gönderilmesine olanak tanır. SignalR gerçek zamanlı istemciden sunucuya ve sunucudan istemciye iletişimi mümkün kılmak için gereken her şeyi gerçekleştirir.
Hub'ları yapılandırın SignalR
Hub'ların SignalR için gereken hizmetleri kaydetmek amacıyla AddSignalR'da Program.cs çağrısını yapın.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
Uç noktaları yapılandırmak için SignalR öğesini ve aynı zamanda MapHub, Program.cs çağırın.
app.MapRazorPages();
app.MapHub<ChatHub>("/Chat");
app.Run();
Note
ASP.NET Core SignalR sunucu tarafı derlemeleri artık .NET Core SDK ile yüklenir. Daha fazla bilgi için SignalR paylaşılan çerçevedeki derlemeler konusuna bakın.
Hub oluşturma ve kullanma
öğesinden Hubdevralan bir sınıf bildirerek bir hub oluşturun. İstemcilerden çağrılabilen hale getirmek için sınıfına yöntemler ekleyin public :
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
}
Note
- Hub sınıfının bir özelliğinde durumu depolamayın. Her hub yöntemi çağrısı yeni bir hub örneğinde yürütülür.
- Bağımlılık ekleme yoluyla direkt bir hub örneği oluşturmayın. Uygulamanızın başka bir yerinden bir istemciye ileti göndermek için kullanın
IHubContext. - Asenkron yöntemlerin hub'ın hayatta kalmasına bağlı olduğu durumlarda
awaitkullanın. Örneğin,Clients.All.SendAsync(...)olmadanawaitgibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
Hub sınıfı, bağlantı hakkında bilgi içeren ve aşağıdaki özellikleri barındıran bir Context özelliği içerir.
| Property | Description |
|---|---|
| ConnectionId | Bağlantının SignalR tarafından atanan benzersiz kimliğini alır. Her bağlantı için bir bağlantı kimliği vardır. |
| UserIdentifier | Kullanıcı tanımlayıcısını alır. Varsayılan olarak, SignalR, bağlantıyla ilişkilendirilmiş ClaimTypes.NameIdentifier'den ClaimsPrincipal'i kullanıcı tanımlayıcısı olarak kullanır. |
| User | Geçerli kullanıcıyla ilişkili olan ClaimsPrincipal öğesini alır. |
| Items | Bu bağlantı kapsamında veri paylaşmak için kullanılabilecek bir anahtar/değer koleksiyonu alır. Veriler bu koleksiyonda depolanabilir ve farklı hub yöntemi çağrıları arasında bağlantı için kalıcı olur. |
| Features | Bağlantıdaki kullanılabilen özelliklerin koleksiyonunu alır. Şimdilik bu koleksiyon çoğu senaryoda gerekli olmadığından henüz ayrıntılı olarak belgelenmemiştir. |
| ConnectionAborted | Bağlantı durdurulduğunda bunu bildiren bir CancellationToken alır. |
Hub.Context ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| GetHttpContext |
HttpContext bağlantıyı döndürür veya bağlantı bir HTTP isteğiyle ilişkilendirilmemişse null döndürür. HTTP bağlantıları için, HTTP üst bilgileri ve sorgu dizeleri gibi bilgileri almak için bu yöntemi kullanın. |
| Abort | Bağlantıyı iptal eder. |
İstemci nesnesi
sınıfı, Hub sunucu ve istemci arasındaki iletişim için aşağıdaki özellikleri içeren bir Clients özellik içerir:
| Property | Description |
|---|---|
| All | Tüm bağlı istemcilerde bir yöntemi çağırır |
| Caller | İstemcide hub yöntemini çağıran bir yöntemi çağırır |
| Others | Yöntemini çağıran istemci dışındaki tüm bağlı istemcilerde bir yöntemi çağırır |
Hub.Clients ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| AllExcept | Belirtilen bağlantılar dışında tüm bağlı istemcilerde bir yöntemi çağırır |
| Client | Belirli bir bağlı istemcide bir yöntemi çağırır |
| Clients | Belirli bağlı istemcilerde bir yöntemi çağırır |
| Group | Belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| GroupExcept | Belirtilen bağlantılar dışında belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| Groups | Birden çok bağlantı grubunda bir yöntemi çağırır |
| OthersInGroup | Hub yöntemini çağıran istemci hariç olmak üzere bir bağlantı grubundaki bir yöntemi çağırır |
| User | Belirli bir kullanıcıyla ilişkili tüm bağlantılarda bir yöntemi çağırır |
| Users | Belirtilen kullanıcılarla ilişkili tüm bağlantılarda bir yöntemi çağırır |
Yukarıdaki tablolardaki her özellik veya yöntem, bir SendAsync yöntemine sahip bir nesne döndürür.
SendAsync yöntemi, çağrılacak olan istemci yönteminin adını ve herhangi bir parametreyi alır.
İstemcilere ileti gönderme
Belirli istemcilere çağrı yapmak için nesnesinin Clients özelliklerini kullanın. Aşağıdaki örnekte üç hub yöntemi vardır:
-
SendMessagekullanarakClients.Alltüm bağlı istemcilere bir ileti gönderir. -
SendMessageToCallerkullanarakClients.Callerçağırana bir ileti gönderir. -
SendMessageToGroupgruptakiSignalR Userstüm istemcilere bir ileti gönderir.
public async Task SendMessage(string user, string message)
=> await Clients.All.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.SendAsync("ReceiveMessage", user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
Kesin türemiş hub'lar
kullanmanın SendAsync bir dezavantajı, çağrılacak istemci yöntemini belirtmek için bir dizeye bağlı olmasıdır. Bu, yöntem adı yanlış yazılmışsa veya istemcide eksikse kodu çalışma zamanı hatalarına açık bırakır.
SendAsync kullanmak yerine, Hub sınıfını Hub<T> ile güçlü bir şekilde tip belirlemektir. Aşağıdaki örnekte, ChatHub istemci yöntemi, adlı IChatClient isimli bir arabirime çıkartılmıştır.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Bu arabirim, önceki ChatHub örneği kesin olarak yazılacak şekilde yeniden düzenleme amacıyla kullanılabilir:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
=> await Clients.All.ReceiveMessage(user, message);
public async Task SendMessageToCaller(string user, string message)
=> await Clients.Caller.ReceiveMessage(user, message);
public async Task SendMessageToGroup(string user, string message)
=> await Clients.Group("SignalR Users").ReceiveMessage(user, message);
}
kullanarak Hub<IChatClient> istemci yöntemlerinin derleme zamanı denetimini etkinleştirir. Bu, Hub<T> yalnızca arabirimde tanımlanan yöntemlere erişim sağlayabildiği için dizelerin kullanılmasından kaynaklanan sorunları önler. Kesin türde bir Hub<T> kullanmak, SendAsync işlevini devre dışı bırakır.
Note
Sonek Async , yöntem adlarından çıkarılmamış.
.on('MyMethodAsync') ile tanımlanmış bir istemci yöntemi olmadığı sürece, MyMethodAsync adını kullanmayın.
Hub yönteminin adını değiştirme
Varsayılan olarak, sunucu hub'ı yöntemi adı .NET yönteminin adıdır. Belirli bir yöntemin bu varsayılan davranışını değiştirmek için HubMethodName özniteliğini kullanın. İstemci, yöntemini çağırırken .NET yöntemi adı yerine bu adı kullanmalıdır:
[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
=> await Clients.User(user).SendAsync("ReceiveMessage", user, message);
Bağlantıdaki olayları yönet
Hubs API, SignalR ve OnConnectedAsync bağlantılarını yönetmek ve izlemek için OnDisconnectedAsync sanal yöntemlerini sağlar. bir istemci hub'a OnConnectedAsync bağlandığında eylemleri gerçekleştirmek için sanal yöntemi geçersiz kılın; örneğin, bunu bir gruba ekleyin:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
İstemci bağlantısı kesildiğinde eylemleri gerçekleştirmek için OnDisconnectedAsync sanal yöntemi geçersiz kılın. İstemcinin bağlantısı kasıtlı olarak, örneğin connection.stop() çağrısı yoluyla kesilirse, exception parametresi null olarak ayarlanır. Ancak, ağ hatası gibi bir hata nedeniyle istemcinin bağlantısı kesilirse, exception parametre hatayı açıklayan bir özel durum içerir:
public override async Task OnDisconnectedAsync(Exception? exception)
{
await base.OnDisconnectedAsync(exception);
}
RemoveFromGroupAsync OnDisconnectedAsync çağrılması gerekmez, sizin için otomatik olarak işlenir.
Hatalarla başa çıkma
Hub yöntemlerinde oluşan özel durumlar, yöntemini çağıran istemciye gönderilir. JavaScript istemcisinde invoke yöntemi bir JavaScript Promisedöndürür. İstemciler, döndürülen söze bir catch işleyici ekleyebilir ya da özel durumları işlemek için try/catch ile async/await kullanabilir.
try {
await connection.invoke("SendMessage", user, message);
} catch (err) {
console.error(err);
}
Bir hub özel durum oluştururken bağlantılar kapatılamaz. Varsayılan olarak, SignalR aşağıdaki örnekte gösterildiği gibi istemciye genel bir hata iletisi döndürür:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'SendMessage' on the server.
Beklenmeyen özel durumlar genellikle veritabanı bağlantısı başarısız olduğunda tetiklenen bir özel durumdaki veritabanı sunucusunun adı gibi hassas bilgiler içerir. SignalR güvenlik önlemi olarak bu ayrıntılı hata iletilerini varsayılan olarak kullanıma sunmaz. Özel durum ayrıntılarının neden gizlendiğini öğrenmek için bkz . ASP.NET Core'da SignalRgüvenlikle ilgili dikkat edilmesi gerekenler.
İstemciye olağanüstü bir koşul yayılması gerekiyorsa sınıfını HubException kullanın.
HubException bir hub yönteminde oluşturulursa, SignalRözel durum iletisinin tamamını değiştirilmemiş olarak istemciye gönderir:
public Task ThrowException()
=> throw new HubException("This error will be sent to the client!");
Note
SignalR yalnızca özel durumun özelliğini istemciye gönderir Message . Özel durumdaki yığın izlemesi ve diğer özellikler istemci tarafından kullanılamaz.
Ek kaynaklar
Tarafından Rachel Appel ve Kevin Griffin
Örnek kodu görüntüleme veya indirme (indirme)
Hub nedir?SignalR
Hubs API'si SignalR , bağlı istemcilerin sunucudaki yöntemleri çağırarak gerçek zamanlı iletişimi kolaylaştırmalarına olanak tanır. Sunucu, istemci tarafından çağrılan yöntemleri, istemci ise sunucu tarafından çağrılan yöntemleri tanımlar. SignalR ayrıca, her zaman Hub tarafından aracılık edilen dolaylı istemciden istemciye iletişimi etkinleştirir ve iletilerin SignalR tek tek istemciler, gruplar veya tüm bağlı istemcilere gönderilmesine olanak tanır. SignalR gerçek zamanlı istemciden sunucuya ve sunucudan istemciye iletişimi mümkün kılmak için gereken her şeyi gerçekleştirir.
Hub'ları yapılandırın SignalR
SignalR ara yazılım, AddSignalR çağrılarak yapılandırılan bazı hizmetleri gerektirir.
services.AddSignalR();
bir ASP.NET Core uygulamasına SignalR işlevselliğini eklerken, SignalR yönteminin MapHub geri çağırmasında Startup.Configure çağırarak UseEndpoints rotalarını ayarlayın.
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
});
Note
ASP.NET Core SignalR sunucu tarafı derlemeleri artık .NET Core SDK ile yüklenir. Daha fazla bilgi için SignalR paylaşılan çerçevedeki derlemeler konusuna bakın.
Hub oluşturma ve kullanma
öğesinden Hubdevralan bir sınıf bildirerek bir hub oluşturun ve genel yöntemler ekleyin. İstemciler olarak publictanımlanan yöntemleri çağırabilir:
public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Herhangi bir C# yönteminde olduğu gibi, karmaşık türler ve diziler de dahil olmak üzere bir dönüş türü ve parametreleri belirtebilirsiniz. SignalR parametrelerinizdeki karmaşık nesnelerin ve dizilerin serileştirilmesini ve deserileştirilmesini yönetir.
Note
Hub'lar geçicidir:
- Durumu hub sınıfındaki bir özellikte depolamayın. Her hub yöntemi çağrısı yeni bir hub örneğinde yürütülür.
- Bağımlılık ekleme yoluyla direkt bir hub örneği oluşturmayın. Uygulamanızın başka bir yerinden bir istemciye ileti göndermek için kullanın
IHubContext. - Asenkron yöntemlerin hub'ın hayatta kalmasına bağlı olduğu durumlarda
awaitkullanın. Örneğin,Clients.All.SendAsync(...)olmadanawaitgibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
sınıfı, Hub özelliği ile bağlantı hakkında bilgi veren aşağıdaki özelliklere sahiptir:
| Property | Description |
|---|---|
| ConnectionId | Bağlantının SignalR tarafından atanan benzersiz kimliğini alır. Her bağlantı için bir bağlantı kimliği vardır. |
| UserIdentifier | Kullanıcı tanımlayıcısını alır. Varsayılan olarak, SignalR, bağlantıyla ilişkilendirilmiş ClaimTypes.NameIdentifier'den ClaimsPrincipal'i kullanıcı tanımlayıcısı olarak kullanır. |
| User | Geçerli kullanıcıyla ilişkili olan ClaimsPrincipal öğesini alır. |
| Items | Bu bağlantı kapsamında veri paylaşmak için kullanılabilecek bir anahtar/değer koleksiyonu alır. Veriler bu koleksiyonda depolanabilir ve farklı hub yöntemi çağrıları arasında bağlantı için kalıcı olur. |
| Features | Bağlantıdaki kullanılabilen özelliklerin koleksiyonunu alır. Şimdilik bu koleksiyon çoğu senaryoda gerekli olmadığından henüz ayrıntılı olarak belgelenmemiştir. |
| ConnectionAborted | Bağlantı durdurulduğunda bunu bildiren bir CancellationToken alır. |
Hub.Context ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| GetHttpContext |
HttpContext bağlantıyı döndürür veya bağlantı bir HTTP isteğiyle ilişkilendirilmemişse null döndürür. HTTP bağlantıları için, HTTP üst bilgileri ve sorgu dizeleri gibi bilgileri almak için bu yöntemi kullanabilirsiniz. |
| Abort | Bağlantıyı iptal eder. |
İstemci nesnesi
sınıfı, Hub sunucu ve istemci arasındaki iletişim için aşağıdaki özellikleri içeren bir Clients özelliğe sahiptir:
| Property | Description |
|---|---|
| All | Tüm bağlı istemcilerde bir yöntemi çağırır |
| Caller | İstemcide hub yöntemini çağıran bir yöntemi çağırır |
| Others | Yöntemini çağıran istemci dışındaki tüm bağlı istemcilerde bir yöntemi çağırır |
Hub.Clients ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| AllExcept | Belirtilen bağlantılar dışında tüm bağlı istemcilerde bir yöntemi çağırır |
| Client | Belirli bir bağlı istemcide bir yöntemi çağırır |
| Clients | Belirli bağlı istemcilerde bir yöntemi çağırır |
| Group | Belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| GroupExcept | Belirtilen bağlantılar dışında belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| Groups | Birden çok bağlantı grubunda bir yöntemi çağırır |
| OthersInGroup | Hub yöntemini çağıran istemci hariç olmak üzere bir bağlantı grubundaki bir yöntemi çağırır |
| User | Belirli bir kullanıcıyla ilişkili tüm bağlantılarda bir yöntemi çağırır |
| Users | Belirtilen kullanıcılarla ilişkili tüm bağlantılarda bir yöntemi çağırır |
Yukarıdaki tablolardaki her özellik veya yöntem, bir SendAsync yöntemine sahip bir nesne döndürür. yöntemi, SendAsync çağrılacak istemci yönteminin adını ve parametrelerini sağlamanıza olanak tanır.
İstemcilere ileti gönderme
Belirli istemcilere çağrı yapmak için nesnesinin Clients özelliklerini kullanın. Aşağıdaki örnekte üç Hub yöntemi vardır:
-
SendMessagekullanarakClients.Alltüm bağlı istemcilere bir ileti gönderir. -
SendMessageToCallerkullanarakClients.Callerçağırana bir ileti gönderir. -
SendMessageToGroupgruptakiSignalR Userstüm istemcilere bir ileti gönderir.
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string user, string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}
Kesin türemiş hub'lar
kullanmanın SendAsync bir dezavantajı, çağrılacak istemci yöntemini belirtmek için sihirli bir dizeye bağlı olmasıdır. Bu, yöntem adı yanlış yazılmışsa veya istemcide eksikse kodu çalışma zamanı hatalarına açık bırakır.
SendAsync kullanmaya bir alternatif, Hub'i Hub<T> ile kesin olarak yazmaktır. Aşağıdaki örnekte, ChatHub istemci yöntemleri IChatClient adlı bir arabirime taşınmıştır.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Bu arabirim, önceki ChatHub örneği yeniden düzenlemek için kullanılabilir:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.ReceiveMessage(user, message);
}
}
kullanarak Hub<IChatClient> istemci yöntemlerinin derleme zamanı denetimini etkinleştirir. Bu, Hub<T> yalnızca arabirimde tanımlanan yöntemlere erişim sağlayabildiği için sihirli dizelerin kullanılmasından kaynaklanan sorunları önler.
Kesin türde bir Hub<T> kullanmak, SendAsync işlevini devre dışı bırakır. Arabirimde tanımlanan tüm yöntemler yine de zaman uyumsuz olarak tanımlanabilir. Aslında, bu yöntemlerin her biri bir Taskdöndürmelidir. Bu bir arabirim olduğundan anahtar sözcüğünü async kullanmayın. Örneğin:
public interface IClient
{
Task ClientMethod();
}
Note
Sonek Async yöntem adından çıkartılmamış. İstemci yönteminiz .on('MyMethodAsync') olarak tanımlanmadıkça, MyMethodAsync ad olarak kullanmamalısınız.
Hub yönteminin adını değiştirme
Varsayılan olarak, sunucu hub'ı yöntemi adı .NET yönteminin adıdır. Ancak, bu varsayılanı değiştirmek ve yöntem için el ile bir ad belirtmek için HubMethodName özniteliğini kullanabilirsiniz. İstemci, yöntemini çağırırken .NET yöntemi adı yerine bu adı kullanmalıdır:
[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}
Bağlantıdaki olayları yönet
Hubs API, SignalR ve OnConnectedAsync bağlantılarını yönetmek ve izlemek için OnDisconnectedAsync sanal yöntemlerini sağlar. İstemci Hub'a OnConnectedAsync bağlandığında eylemleri gerçekleştirmek için sanal yöntemi geçersiz kılın; örneğin, bunu bir gruba ekleyin:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
İstemci bağlantısı kesildiğinde eylemleri gerçekleştirmek için OnDisconnectedAsync sanal yöntemi geçersiz kılın. İstemci bilerek bağlantıyı keserse (örneğin çağrı connection.stop() yaparak), exception parametresi null olur. Ancak, istemcinin bağlantısı bir hata (ağ hatası gibi) exception nedeniyle kesilirse, parametre hatayı açıklayan bir özel durum içerir:
public override async Task OnDisconnectedAsync(Exception exception)
{
await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", "I", "disconnect");
await base.OnDisconnectedAsync(exception);
}
RemoveFromGroupAsync OnDisconnectedAsync çağrılması gerekmez, sizin için otomatik olarak işlenir.
Warning
Güvenlik uyarısı: ConnectionId ifşa edilirse, SignalR sunucu veya istemci sürümü ASP.NET Core 2.2 veya önceki sürümlerden biri olduğunda kötü amaçlı kimliğe bürünmeye neden olabilir.
Hatalarla başa çıkma
Hub yöntemlerinde oluşan istisnalar, yöntemi çağıran istemciye gönderilir. JavaScript istemcisinde invoke yöntemi bir JavaScript Promisedöndürür. İstemci, catch kullanarak promise'e bağlı bir işleyici ile bir hata aldığında, bu işleyici çağrılır ve bir JavaScript Error nesnesi olarak geçirilir.
connection.invoke("SendMessage", user, message).catch(err => console.error(err));
Hub'ınız bir istisna fırlatırsa bağlantılar kapanmaz. Varsayılan olarak, SignalR istemciye genel bir hata iletisi döndürür. Örneğin:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.
Beklenmeyen özel durumlar genellikle veritabanı bağlantısı başarısız olduğunda tetiklenen bir özel durumdaki veritabanı sunucusunun adı gibi hassas bilgiler içerir. SignalR güvenlik önlemi olarak bu ayrıntılı hata iletilerini varsayılan olarak kullanıma sunmaz. Özel durum ayrıntılarının neden gizlendiğini öğrenmek için bkz . ASP.NET Core'da SignalRgüvenlikle ilgili dikkat edilmesi gerekenler.
İstemciye iletmek istediğiniz olağanüstü bir durumunuz varsa sınıfını HubException kullanabilirsiniz. Hub yönteminizden bir HubException oluşturursanız, SignalR iletinin tamamı değiştirilmemiş olarak istemciye gönderilir:
public Task ThrowException()
{
throw new HubException("This error will be sent to the client!");
}
Note
SignalR yalnızca özel durumun özelliğini istemciye gönderir Message . Özel durumdaki yığın izlemesi ve diğer özellikler istemci tarafından kullanılamaz.
Ek kaynaklar
Tarafından Rachel Appel ve Kevin Griffin
Örnek kodu görüntüleme veya indirme (indirme)
Hub nedir?SignalR
Hubs API'si SignalR , bağlı istemcilerin sunucudaki yöntemleri çağırarak gerçek zamanlı iletişimi kolaylaştırmalarına olanak tanır. Sunucu, istemci tarafından çağrılan yöntemleri, istemci ise sunucu tarafından çağrılan yöntemleri tanımlar. SignalR ayrıca, her zaman Hub tarafından aracılık edilen dolaylı istemciden istemciye iletişimi etkinleştirir ve iletilerin SignalR tek tek istemciler, gruplar veya tüm bağlı istemcilere gönderilmesine olanak tanır. SignalR gerçek zamanlı istemciden sunucuya ve sunucudan istemciye iletişimi mümkün kılmak için gereken her şeyi gerçekleştirir.
Hub'ları yapılandırın SignalR
SignalR ara yazılım, AddSignalR çağrılarak yapılandırılan bazı hizmetleri gerektirir.
services.AddSignalR();
ASP.NET Core uygulamasına SignalR işlevselliği eklerken, SignalR yönteminde UseSignalRStartup.Configure çağırarak yolları ayarlayın.
app.UseSignalR(route =>
{
route.MapHub<ChatHub>("/chathub");
});
Hub oluşturma ve kullanma
öğesinden Hubdevralan bir sınıf bildirerek bir hub oluşturun ve genel yöntemler ekleyin. İstemciler olarak publictanımlanan yöntemleri çağırabilir:
public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Herhangi bir C# yönteminde olduğu gibi, karmaşık türler ve diziler de dahil olmak üzere bir dönüş türü ve parametreleri belirtebilirsiniz. SignalR parametrelerinizdeki karmaşık nesnelerin ve dizilerin serileştirilmesini ve deserileştirilmesini yönetir.
Note
Hub'lar geçicidir:
- Durumu hub sınıfındaki bir özellikte depolamayın. Her hub yöntemi çağrısı yeni bir hub örneğinde yürütülür.
- Bağımlılık ekleme yoluyla direkt bir hub örneği oluşturmayın. Uygulamanızın başka bir yerinden bir istemciye ileti göndermek için kullanın
IHubContext. - Asenkron yöntemlerin hub'ın hayatta kalmasına bağlı olduğu durumlarda
awaitkullanın. Örneğin,Clients.All.SendAsync(...)olmadanawaitgibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
sınıfı, Hub özelliği ile bağlantı hakkında bilgi veren aşağıdaki özelliklere sahiptir:
| Property | Description |
|---|---|
| ConnectionId | Bağlantının SignalR tarafından atanan benzersiz kimliğini alır. Her bağlantı için bir bağlantı kimliği vardır. |
| UserIdentifier | Kullanıcı tanımlayıcısını alır. Varsayılan olarak, SignalR, bağlantıyla ilişkilendirilmiş ClaimTypes.NameIdentifier'den ClaimsPrincipal'i kullanıcı tanımlayıcısı olarak kullanır. |
| User | Geçerli kullanıcıyla ilişkili olan ClaimsPrincipal öğesini alır. |
| Items | Bu bağlantı kapsamında veri paylaşmak için kullanılabilecek bir anahtar/değer koleksiyonu alır. Veriler bu koleksiyonda depolanabilir ve farklı hub yöntemi çağrıları arasında bağlantı için kalıcı olur. |
| Features | Bağlantıdaki kullanılabilen özelliklerin koleksiyonunu alır. Şimdilik bu koleksiyon çoğu senaryoda gerekli olmadığından henüz ayrıntılı olarak belgelenmemiştir. |
| ConnectionAborted | Bağlantı durdurulduğunda bunu bildiren bir CancellationToken alır. |
Hub.Context ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| GetHttpContext |
HttpContext bağlantıyı döndürür veya bağlantı bir HTTP isteğiyle ilişkilendirilmemişse null döndürür. HTTP bağlantıları için, HTTP üst bilgileri ve sorgu dizeleri gibi bilgileri almak için bu yöntemi kullanabilirsiniz. |
| Abort | Bağlantıyı iptal eder. |
İstemci nesnesi
sınıfı, Hub sunucu ve istemci arasındaki iletişim için aşağıdaki özellikleri içeren bir Clients özelliğe sahiptir:
| Property | Description |
|---|---|
| All | Tüm bağlı istemcilerde bir yöntemi çağırır |
| Caller | İstemcide hub yöntemini çağıran bir yöntemi çağırır |
| Others | Yöntemini çağıran istemci dışındaki tüm bağlı istemcilerde bir yöntemi çağırır |
Hub.Clients ayrıca aşağıdaki yöntemleri içerir:
| Method | Description |
|---|---|
| AllExcept | Belirtilen bağlantılar dışında tüm bağlı istemcilerde bir yöntemi çağırır |
| Client | Belirli bir bağlı istemcide bir yöntemi çağırır |
| Clients | Belirli bağlı istemcilerde bir yöntemi çağırır |
| Group | Belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| GroupExcept | Belirtilen bağlantılar dışında belirtilen gruptaki tüm bağlantılarda bir yöntemi çağırır |
| Groups | Birden çok bağlantı grubunda bir yöntemi çağırır |
| OthersInGroup | Hub yöntemini çağıran istemci hariç olmak üzere bir bağlantı grubundaki bir yöntemi çağırır |
| User | Belirli bir kullanıcıyla ilişkili tüm bağlantılarda bir yöntemi çağırır |
| Users | Belirtilen kullanıcılarla ilişkili tüm bağlantılarda bir yöntemi çağırır |
Yukarıdaki tablolardaki her özellik veya yöntem, bir SendAsync yöntemine sahip bir nesne döndürür. yöntemi, SendAsync çağrılacak istemci yönteminin adını ve parametrelerini sağlamanıza olanak tanır.
İstemcilere ileti gönderme
Belirli istemcilere çağrı yapmak için nesnesinin Clients özelliklerini kullanın. Aşağıdaki örnekte üç Hub yöntemi vardır:
-
SendMessagekullanarakClients.Alltüm bağlı istemcilere bir ileti gönderir. -
SendMessageToCallerkullanarakClients.Callerçağırana bir ileti gönderir. -
SendMessageToGroupgruptakiSignalR Userstüm istemcilere bir ileti gönderir.
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToGroup(string user, string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message);
}
Kesin türemiş hub'lar
kullanmanın SendAsync bir dezavantajı, çağrılacak istemci yöntemini belirtmek için sihirli bir dizeye bağlı olmasıdır. Bu, yöntem adı yanlış yazılmışsa veya istemcide eksikse kodu çalışma zamanı hatalarına açık bırakır.
SendAsync kullanmaya bir alternatif, Hub'i Hub<T> ile kesin olarak yazmaktır. Aşağıdaki örnekte, ChatHub istemci yöntemleri IChatClient adlı bir arabirime taşınmıştır.
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
}
Bu arabirim, önceki ChatHub örneği yeniden düzenlemek için kullanılabilir:
public class StronglyTypedChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string user, string message)
{
return Clients.Caller.ReceiveMessage(user, message);
}
}
kullanarak Hub<IChatClient> istemci yöntemlerinin derleme zamanı denetimini etkinleştirir. Bu, Hub<T> yalnızca arabirimde tanımlanan yöntemlere erişim sağlayabildiği için sihirli dizelerin kullanılmasından kaynaklanan sorunları önler.
Kesin türde bir Hub<T> kullanmak, SendAsync işlevini devre dışı bırakır. Arabirimde tanımlanan tüm yöntemler yine de zaman uyumsuz olarak tanımlanabilir. Aslında, bu yöntemlerin her biri bir Taskdöndürmelidir. Bu bir arabirim olduğundan anahtar sözcüğünü async kullanmayın. Örneğin:
public interface IClient
{
Task ClientMethod();
}
Note
Sonek Async yöntem adından çıkartılmamış. İstemci yönteminiz .on('MyMethodAsync') olarak tanımlanmadıkça, MyMethodAsync ad olarak kullanmamalısınız.
Hub yönteminin adını değiştirme
Varsayılan olarak, sunucu hub'ı yöntemi adı .NET yönteminin adıdır. Ancak, bu varsayılanı değiştirmek ve yöntem için el ile bir ad belirtmek için HubMethodName özniteliğini kullanabilirsiniz. İstemci, yöntemini çağırırken .NET yöntemi adı yerine bu adı kullanmalıdır:
[HubMethodName("SendMessageToUser")]
public Task DirectMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", user, message);
}
Bağlantıdaki olayları yönet
Hubs API, SignalR ve OnConnectedAsync bağlantılarını yönetmek ve izlemek için OnDisconnectedAsync sanal yöntemlerini sağlar. İstemci Hub'a OnConnectedAsync bağlandığında eylemleri gerçekleştirmek için sanal yöntemi geçersiz kılın; örneğin, bunu bir gruba ekleyin:
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
İstemci bağlantısı kesildiğinde eylemleri gerçekleştirmek için OnDisconnectedAsync sanal yöntemi geçersiz kılın. İstemci bilerek bağlantıyı keserse (örneğin çağrı connection.stop() yaparak), exception parametresi null olur. Ancak, istemcinin bağlantısı bir hata (ağ hatası gibi) exception nedeniyle kesilirse, parametre hatayı açıklayan bir özel durum içerir:
public override async Task OnDisconnectedAsync(Exception exception)
{
await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", "I", "disconnect");
await base.OnDisconnectedAsync(exception);
}
RemoveFromGroupAsync OnDisconnectedAsync çağrılması gerekmez, sizin için otomatik olarak işlenir.
Warning
Güvenlik uyarısı: ConnectionId ifşa edilirse, SignalR sunucu veya istemci sürümü ASP.NET Core 2.2 veya önceki sürümlerden biri olduğunda kötü amaçlı kimliğe bürünmeye neden olabilir.
Hatalarla başa çıkma
Hub yöntemlerinde oluşan istisnalar, yöntemi çağıran istemciye gönderilir. JavaScript istemcisinde invoke yöntemi bir JavaScript Promisedöndürür. İstemci, catch kullanarak promise'e bağlı bir işleyici ile bir hata aldığında, bu işleyici çağrılır ve bir JavaScript Error nesnesi olarak geçirilir.
connection.invoke("SendMessage", user, message).catch(err => console.error(err));
Hub'ınız bir istisna fırlatırsa bağlantılar kapanmaz. Varsayılan olarak, SignalR istemciye genel bir hata iletisi döndürür. Örneğin:
Microsoft.AspNetCore.SignalR.HubException: An unexpected error occurred invoking 'MethodName' on the server.
Beklenmeyen özel durumlar genellikle veritabanı bağlantısı başarısız olduğunda tetiklenen bir özel durumdaki veritabanı sunucusunun adı gibi hassas bilgiler içerir. SignalR güvenlik önlemi olarak bu ayrıntılı hata iletilerini varsayılan olarak kullanıma sunmaz. Özel durum ayrıntılarının neden gizlendiğini öğrenmek için bkz . ASP.NET Core'da SignalRgüvenlikle ilgili dikkat edilmesi gerekenler.
İstemciye iletmek istediğiniz olağanüstü bir durumunuz varsa sınıfını HubException kullanabilirsiniz. Hub yönteminizden bir HubException oluşturursanız, SignalR iletinin tamamı değiştirilmemiş olarak istemciye gönderilir:
public Task ThrowException()
{
throw new HubException("This error will be sent to the client!");
}
Note
SignalR yalnızca özel durumun özelliğini istemciye gönderir Message . Özel durumdaki yığın izlemesi ve diğer özellikler istemci tarafından kullanılamaz.
Ek kaynaklar
ASP.NET Core