Blazor WebAssembly: Bidirektionale Kommunikation und Benachrichtigungen

Wie lassen sich durch bidirektionale Kommunikation mehrere Blazor-Anwendungsinstanzen gegenseitig zur Synchronisation der Inhalte benachrichtigen?

In Pocket speichern vorlesen Druckansicht 3 Kommentare lesen
Lesezeit: 13 Min.
Von
  • Dr. Holger Schwichtenberg
Inhaltsverzeichnis

Nutzer der in den ersten Artikeln dieses fünfteiligen Tutorials vorgestellten Aufgabenverwaltung "MiracleList" könnten diese parallel in mehreren Browserfenster und auf mehreren Systemen öffnen. Für den Fall wäre es schön, wenn die Änderungen in einem Fenster sofort in anderen sichtbar würden, wie man es in Abbildung 1 sieht. Das soll realisiert werden in Form einer Benachrichtigung, die der Backend-Webserver an alle MiracleList-Instanzen der Nutzer aussendet. Die Instanzen können dann selbst entscheiden, ob sie die Daten neu laden wollen oder gerade eine andere Ansicht zeigen, für die die neuen Daten nicht relevant sind.

Benutzeroberflächenaktualisierung zwischen Chrome (links) und Firefox (rechts) (Abb. 1)

Die Bibliothek ASP.NET Core SignalR (Vorgänger im klassischen .NET Framework war ASP.NET SignalR – ohne Core) erlaubt eine bidirektionale Kommunikation zwischen einem Client (oft ein Browser, aber auch anderen Anwendungsarten sind möglich) und einem Webserver. Somit kann nicht nur der Client eine Nachricht an den Webserver senden, sondern auch der Webserver die Clients benachrichtigen. Abhängig von den Fähigkeiten der beteiligten Systeme werden die Nachrichten auf Basis von Websockets, Server-Sent Events (SSE) oder Long Polling übermittelt. Damit haben Entwickler und Benutzer nichts zu tun; ASP.NET Core SignalR entscheidet selbst zur Laufzeit über das Verfahren. Eine manuelle Vergabe ist aber möglich.

Blazor-Tutorial

Im MiracleList-Backend ist für ASP.NET Core SignalR ein sogenannter Hub realisiert. Das Backend basiert auf ASP.NET Core und dort ist SignalR bereits enthalten. Dieser Hub ist zum besseren Verständnis in Listing 1 wiedergeben:

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
 
namespace MiracleList_Backend.Hubs
{
 /// <summary>
 /// ASP.NET Core SignalR Hub
 /// </summary>
 public class MLHub : Hub
 {
  public async Task Register(string user)
  {
   await Groups.AddToGroupAsync(Context.ConnectionId, user);
  }
 
  public async Task SendCategoryListUpdate(string user)
  {
   // Sende Benachrichtigung an die ganze Gruppe
   await Clients.Groups(user).SendAsync("CategoryListUpdate", Context.ConnectionId);
  }
 
  public async Task SendTaskListUpdate(string user, int categoryID)
  {
   // Sende Benachrichtigung an die ganze Gruppe
   await Clients.Groups(user).SendAsync("TaskListUpdate", Context.ConnectionId, categoryID);
  }
 }
}

Listing 1: Implementierung des ASP.NET Core SignalR Hub

Der Hub implementiert drei Methoden:

  • Register() wird aufgerufen, wenn ein MiracleList-Client nach der Benutzeranmeldung die Hauptanwendungsseite betritt. Hier registrieren sich Benutzer für Aktualisierungen durch andere Clients, die unter gleichem Benutzernamen laufen.
  • SendCategoryListUpdate() wird gerufen, wenn sich die Kategorienliste der Benutzer ändert. Einziger Parameter ist die eindeutige Benutzeridentifikation. Bei der aus dem Hub ausgehenden Nachricht an die angeschlossenen Clients wird die ConnectionId des auslösenden Clients als Parameter übermittelt. Das dient hier nur Demonstrations- und Diagnosezwecken.
  • SendTaskListUpdate() wird gerufen, wenn sich die Aufgabenliste einer Kategorie der Benutzer ändert. Hier wird neben der ConnectionId auch die in diesem Fall wichtige categoryID übermittelt, denn die Benutzeroberfläche des Clients soll sich nur aktualisieren, wenn sie die gleiche Kategorie anzeigt.

Bewusst übermitteln SendCategoryListUpdate() und SendTaskListUpdate() nicht die eigentlichen Daten (also die geänderte Kategorien- oder Aufgabenlisten). Es bleibt den angeschlossenen Clients überlassen, die Daten bei Bedarf aus der Datenbank beziehungsweise der WebAPI abzuholen. Sonst würden sie unnötige Daten im Netzwerk versenden, zum Beispiel wenn Benutzer aktuell in einer anderen Kategorie arbeiten.