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, 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 Program.cs'da AddSignalR ç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 paylaşılan çerçevedeki derlemelere 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,awaitolmadanClients.All.SendAsync(...)gibi 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ş ClaimsPrincipal'den ClaimTypes.NameIdentifier'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 Clients özelliği üzerinden Client(...) veya Caller ç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, IHubContext<T> örneğinde Client(...) ç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ğımlılık Enjeksiyonu'nda anahtarlı hizmetler desteği
Anahtarlı hizmetler , anahtarları kullanarak Bağımlılık Ekleme (DI) hizmetlerini kaydetmeye ve almaya yönelik bir mekanizmayı ifade eder. Bir hizmet, AddKeyedSingleton (veya AddKeyedScoped ya da AddKeyedTransient) çağrılarak bir anahtarla ilişkilendirilir. Özniteliği [FromKeyedServices] ile anahtarı belirterek kayıtlı bir hizmete erişin. 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ı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 içinde çağrılmasına gerek yoktur, sizin yerinize 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 Program.cs'da AddSignalR ç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 paylaşılan çerçevedeki derlemelere 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,awaitolmadanClients.All.SendAsync(...)gibi 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ş ClaimsPrincipal'den ClaimTypes.NameIdentifier'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 Clients özelliği üzerinden Client(...) veya Caller ç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, IHubContext<T> örneğinde Client(...) ç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 Program.cs'da AddSignalR ç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 paylaşılan çerçevedeki derlemelere 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,awaitolmadanClients.All.SendAsync(...)gibi 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ş ClaimsPrincipal'den ClaimTypes.NameIdentifier'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, Startup.Configure yönteminin UseEndpoints geri çağırmasında MapHub çağırarak SignalR 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 paylaşılan çerçevedeki derlemelere 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,awaitolmadanClients.All.SendAsync(...)gibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
sınıfı, Context ö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ş ClaimsPrincipal'den ClaimTypes.NameIdentifier'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, Startup.Configure yönteminde SignalRUseSignalR ç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,awaitolmadanClients.All.SendAsync(...)gibi bir yöntem çağrıldığında veSendAsyncbitmeden önce hub yöntemi tamamlarsa başarısız olabilir.
Bir Context nesnesi
sınıfı, Context ö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ş ClaimsPrincipal'den ClaimTypes.NameIdentifier'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