Gruplar, Kullanıcılar ve Bağlantı Yönetimi
Grupları yönetin, belirli kullanıcıları veya bağlantıları hedefleyin ve bağlanma/bağlantı kesme yaşam döngüsü olaylarını yönetin.
Gruplar, Kullanıcılar ve Bağlantı Yönetimi, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.
Gruplar ve Kullanıcılar Neden?
Gerçek uygulamalarda nadiren ALL istemcilere yayın yapmak istersiniz. SignalR'ın grupları bağlantı kümelerini (örneğin bir sohbet odasını) hedeflemenizi, kullanıcılar ise belirli bir kimliği doğrulanmış kullanıcıya ait tüm bağlantılara ulaşmanızı sağlar.
Bağlantıları Gruplara Ekleme
Bağlantı kimliği ve grup adıyla Groups.AddToGroupAsync() çağrısını yapın. Bir bağlantı aynı anda birden çok gruba ait olabilir.
public class ChatHub : Hub
{
public async Task JoinRoom(string roomName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
await Clients.Group(roomName)
.SendAsync("UserJoined", Context.User!.Identity!.Name);
}
public async Task LeaveRoom(string roomName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomName);
await Clients.Group(roomName)
.SendAsync("UserLeft", Context.User!.Identity!.Name);
}
}Gruplara Gönderme
Bir gruptaki tüm bağlantılara göndermek için Clients.Group(name) kullanın. Diğer hedefleme seçenekleri arasında GroupExcept ve Groups (aynı anda birden çok grup) bulunur.
public async Task SendToRoom(string roomName, string message)
{
var sender = Context.User!.Identity!.Name;
// Everyone in the room
await Clients.Group(roomName)
.SendAsync("ReceiveMessage", sender, message);
// Everyone in the room except the sender
await Clients.GroupExcept(roomName, Context.ConnectionId)
.SendAsync("ReceiveMessage", sender, message);
}Kullanıcı Tabanlı Hedefleme
Bir kullanıcının birden çok tarayıcı sekmesi veya açık cihazı olduğunda birden çok bağlantısı bulunur. Clients.User(userId), bu kullanıcının TÜM bağlantılarına aynı anda gönderir.
// Send to all connections of user with ID "user-123"
await Clients.User("user-123")
.SendAsync("Notification", "Your order has shipped!");
// SignalR uses the NameIdentifier claim by default.
// Context.UserIdentifier returns the current user's ID.
var myId = Context.UserIdentifier;
await Clients.User(myId!).SendAsync("Ack", "Server received your message");Özel Kullanıcı Kimliği Sağlayıcısı
SignalR, varsayılan olarak kullanıcı kimliği olarak NameIdentifier talebini kullanır. Farklı bir talep veya özel mantık kullanmak için IUserIdProvider uygulayın.
public class EmailUserIdProvider : IUserIdProvider
{
public string? GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(ClaimTypes.Email)?.Value;
}
}
// Register:
builder.Services.AddSingleton<IUserIdProvider, EmailUserIdProvider>();Bağlantı Durumunu İzleme
SignalR, bağlantı kopmaları arasında bağlantı durumunu kalıcı olarak saklamaz. Kullanıcı kimliklerini bağlantı kimlikleriyle eşleyen kendi eşlemenizi iş parçacığı güvenli bir sözlükte (tek sunucu) veya Redis'te (çok sunucu) tutun.
public class ConnectionTracker
{
private readonly ConcurrentDictionary<string, HashSet<string>> _userConnections
= new();
public void AddConnection(string userId, string connectionId)
=> _userConnections.GetOrAdd(userId, _ => new()).Add(connectionId);
public void RemoveConnection(string userId, string connectionId)
{
if (_userConnections.TryGetValue(userId, out var conns))
{
conns.Remove(connectionId);
if (conns.Count == 0) _userConnections.TryRemove(userId, out _);
}
}
public IEnumerable<string> GetConnections(string userId)
=> _userConnections.TryGetValue(userId, out var c) ? c : Enumerable.Empty<string>();
}OnConnected/OnDisconnected İçinde Grupları Otomatik Yönetme
Yaygın bir örüntü, kimliği doğrulanmış kullanıcıları OnConnectedAsync içinde otomatik olarak kişisel gruplarına eklemektir. Böylece özel izleme yapmadan onları grup adıyla hedefleyebilirsiniz.
public override async Task OnConnectedAsync()
{
// Add to a personal group named by user ID
var userId = Context.UserIdentifier;
if (userId is not null)
await Groups.AddToGroupAsync(Context.ConnectionId, userId);
await base.OnConnectedAsync();
}
// Now send to a user by their personal group:
await _hub.Clients.Group(userId)
.SendAsync("Update", payload);Gruplarla Arka Plan Hizmetlerinden Gönderme
IHubContext kullanarak arka plan hizmetlerinden grupları ve kullanıcıları hedefleyebilirsiniz — sisteminizdeki olayların tetiklediği eşzamansız bildirimler için mükemmeldir.
public class OrderShippedHandler : INotificationHandler<OrderShipped>
{
private readonly IHubContext<OrderHub> _hub;
public OrderShippedHandler(IHubContext<OrderHub> hub) => _hub = hub;
public async Task Handle(OrderShipped notification, CancellationToken ct)
{
// Push to the customer's personal group
await _hub.Clients.Group(notification.CustomerId.ToString())
.SendAsync("OrderShipped",
new { notification.OrderId, notification.TrackingNumber },
ct);
}
}Grup Üyeliğinin Kalıcılığı
Grup üyeliği kalıcı olarak saklanmaz — sunucu yeniden başlatılırsa veya bir Redis arka plan veri yolu durumunu kaybederse gruplar boşalır. İstemcinin onreconnected olayını kullanarak yeniden bağlanıldığında gruplara tekrar katılın.
// JavaScript client: re-join groups after reconnect
connection.onreconnected(async connectionId => {
console.log(`Reconnected as ${connectionId}`);
// Re-join previously joined rooms
for (const room of joinedRooms) {
await connection.invoke("JoinRoom", room);
}
});Çevrimiçi/Çevrimdışı Durum Algılama
OnConnected/OnDisconnected içinde kullanıcı başına bağlantıları sayarak çevrimiçi durumu izleyin ve durum olaylarını ilgili gruplara yayınlayın.
public override async Task OnConnectedAsync()
{
var userId = Context.UserIdentifier!;
var count = _tracker.AddConnection(userId, Context.ConnectionId);
if (count == 1) // first connection for this user
await Clients.Others.SendAsync("UserOnline", userId);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? ex)
{
var userId = Context.UserIdentifier!;
var count = _tracker.RemoveConnection(userId, Context.ConnectionId);
if (count == 0) // no more connections
await Clients.Others.SendAsync("UserOffline", userId);
await base.OnDisconnectedAsync(ex);
}Hızlı Kontrol
Bir kullanıcının üç tarayıcı sekmesi açık olduğunda Clients.User(userId) ne yapar?
Özet: Gruplar, Kullanıcılar ve Bağlantı Yönetimi
Temel çıkarımlar:
Groups.AddToGroupAsync/RemoveFromGroupAsync: grup üyeliğini yönetirClients.Group(name): bağlantıların bir alt kümesine gönderim yaparClients.User(userId): bir kullanıcının tüm bağlantılarına gönderim yapar- Özel kullanıcı kimliği bildirimleri için
IUserIdProvideruygulayın - Gruplar kalıcı olarak saklanmaz — yeniden bağlanıldığında tekrar katılın
- Durum algılama için bağlantı sayılarını ConcurrentDictionary içinde izleyin
Sıkça Sorulan Sorular
“Gruplar, Kullanıcılar ve Bağlantı Yönetimi” dersi ücretsiz mi?
Evet — “Gruplar, Kullanıcılar ve Bağlantı Yönetimi” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.
“Gruplar, Kullanıcılar ve Bağlantı Yönetimi” dersinde ne öğreneceğim?
Grupları yönetin, belirli kullanıcıları veya bağlantıları hedefleyin ve bağlanma/bağlantı kesme yaşam döngüsü olaylarını yönetin. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C# Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Gruplar, Kullanıcılar ve Bağlantı Yönetimi” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- SignalR Hub'ları ve Bağlantılar
- Gruplar, Kullanıcılar ve Bağlantı Yönetimi
- Güçlü Türlendirilmiş Hub'lar
- Redis Backplane ile Ölçekleme