Gruppen, Benutzer und Verbindungsverwaltung
Verwalten Sie Gruppen, richten Sie Nachrichten an bestimmte Benutzer oder Verbindungen und behandeln Sie Ereignisse im Verbindungslebenszyklus.
Gruppen, Benutzer und Verbindungsverwaltung ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum Gruppen und Benutzer?
In echten Anwendungen möchten Sie nur selten an ALLE Clients senden. Mit den Gruppen von SignalR können Sie Teilmengen von Verbindungen ansprechen (z. B. einen Chatraum), und mit Benutzern können Sie alle Verbindungen eines bestimmten authentifizierten Benutzers adressieren.
Verbindungen zu Gruppen hinzufügen
Rufen Sie Groups.AddToGroupAsync() mit der Verbindungs-ID und einem Gruppennamen auf. Eine Verbindung kann gleichzeitig mehreren Gruppen angehören.
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);
}
}An Gruppen senden
Verwenden Sie Clients.Group(name), um an alle Verbindungen in einer Gruppe zu senden. Weitere Optionen zur Zieladressierung sind GroupExcept und Groups (mehrere gleichzeitig).
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);
}Benutzerbasierte Zieladressierung
Wenn ein Benutzer mehrere Browser-Tabs oder Geräte geöffnet hat, verfügt er über mehrere Verbindungen. Clients.User(userId) sendet gleichzeitig an ALLE Verbindungen dieses Benutzers.
// 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");Benutzerdefinierter User-ID-Provider
Standardmäßig verwendet SignalR den NameIdentifier-Claim als Benutzer-ID. Implementieren Sie IUserIdProvider, um einen anderen Claim oder eine benutzerdefinierte Logik zu verwenden.
public class EmailUserIdProvider : IUserIdProvider
{
public string? GetUserId(HubConnectionContext connection)
{
return connection.User?.FindFirst(ClaimTypes.Email)?.Value;
}
}
// Register:
builder.Services.AddSingleton<IUserIdProvider, EmailUserIdProvider>();Den Verbindungszustand verfolgen
SignalR speichert den Verbindungszustand zwischen Verbindungsabbrüchen nicht. Verwalten Sie Ihre eigene Zuordnung von Benutzer-IDs zu Verbindungs-IDs in einem threadsicheren Wörterbuch (ein Server) oder in Redis (mehrere Server).
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>();
}Gruppen in OnConnected/OnDisconnected automatisch verwalten
Ein gängiges Muster besteht darin, authentifizierte Benutzer in OnConnectedAsync automatisch ihrer persönlichen Gruppe hinzuzufügen. So können Sie sie über den Gruppennamen ansprechen, ohne eine eigene Zuordnung verwalten zu müssen.
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);Aus Hintergrunddiensten mit Gruppen senden
Mit IHubContext können Sie aus Hintergrunddiensten Gruppen und Benutzer ansprechen – ideal für asynchrone Benachrichtigungen, die durch Ereignisse in Ihrem System ausgelöst werden.
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);
}
}Dauerhafte Speicherung der Gruppenmitgliedschaft
Die Gruppenmitgliedschaft wird nicht dauerhaft gespeichert – bei einem Neustart des Servers oder wenn ein Redis-Backplane seinen Zustand verliert, sind die Gruppen leer. Treten Sie Gruppen beim Wiederverbinden über das Clientereignis onreconnected erneut bei.
// 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);
}
});Presence: Erkennung von Online-/Offline-Status
Verfolgen Sie den Onlinestatus, indem Sie die Verbindungen pro Benutzer in OnConnected/OnDisconnected zählen und Presence-Ereignisse an relevante Gruppen senden.
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);
}Kurze Überprüfung
Was bewirkt Clients.User(userId), wenn ein Benutzer drei Browser-Tabs geöffnet hat?
Zusammenfassung: Gruppen, Benutzer und Verbindungsverwaltung
Wichtigste Erkenntnisse:
Groups.AddToGroupAsync/RemoveFromGroupAsync: Gruppenmitgliedschaften verwaltenClients.Group(name): an eine Teilmenge von Verbindungen sendenClients.User(userId): an alle Verbindungen eines Benutzers sendenIUserIdProviderfür benutzerdefinierte Benutzer-ID-Claims implementieren- Gruppen werden nicht dauerhaft gespeichert – bei einer erneuten Verbindung wieder beitreten
- Verbindungsanzahlen in ConcurrentDictionary für die Presence-Erkennung verfolgen
Häufig gestellte Fragen
Ist die Lektion „Gruppen, Benutzer und Verbindungsverwaltung“ kostenlos?
Ja — der vollständige Text von „Gruppen, Benutzer und Verbindungsverwaltung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Gruppen, Benutzer und Verbindungsverwaltung“?
Verwalten Sie Gruppen, richten Sie Nachrichten an bestimmte Benutzer oder Verbindungen und behandeln Sie Ereignisse im Verbindungslebenszyklus. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Gruppen, Benutzer und Verbindungsverwaltung“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- SignalR-Hubs und Verbindungen
- Gruppen, Benutzer und Verbindungsverwaltung
- Typsichere Hubs
- Skalierung mit Redis-Backplane