Zum Inhalt springen
Alle Projekte

LiveBoard

Ein kollaboratives Kanban-Board in Echtzeit mit Präsenzanzeige, optimistischer UI, versionsbasierter Konfliktbehandlung und Redis zur Skalierung über mehrere Instanzen.

Art
Nebenprojekt
Tech-Stack
  • NestJS
  • Socket.IO
  • React
  • Redis
Illustration von LiveBoard

Das Problem

Ein gemeinsames Board ist nur nützlich, wenn alle dasselbe sehen. In einer Demo ist das einfach, in der Praxis nicht: Zwei Leute bearbeiten dieselbe Karte, eine Verbindung bricht ab, oder Nutzer landen auf verschiedenen Server-Instanzen. Nichts davon soll die Oberfläche flackern lassen oder still eine Änderung verschlucken.

Was es macht

LiveBoard ist ein Kanban-Board, auf dem Änderungen sofort bei allen ankommen. Karten lassen sich anlegen, bearbeiten, verschieben und löschen. Avatare, Live-Cursor und eine Tipp-Anzeige zeigen, wer gerade da ist, und ein Aktivitätsprotokoll hält jede Änderung fest. Jedes Board ist ein eigener WebSocket-Raum mit Zugriffskontrolle.

Änderungen greifen in der Oberfläche sofort und werden zurückgerollt, wenn der Server sie ablehnt. Nach einem Verbindungsabbruch holt der Client die verpassten Events nach.

Eine Karte verschieben

  1. Der Client verschiebt die Karte, aktualisiert die Oberfläche optimistisch und sendet card:move mit der version der Karte.
  2. Das Gateway prüft das JWT, die Board-Mitgliedschaft und die version.
  3. Die Änderung wird in einer Transaktion in PostgreSQL gespeichert und die version um eins erhöht.
  4. Der Server sendet card:moved an den Board-Raum und über Redis an die anderen Instanzen.
  5. War die Version veraltet, bekommt der Absender card:rejected und synchronisiert neu.
  1. BrowserSocket.IO-Clients
  2. NestJS-Gatewaysmehrere Instanzen
  3. RedisPub/Sub-Adapter
  4. PostgreSQLPrisma
Auch Clients auf unterschiedlichen Gateway-Instanzen sehen die Änderungen der anderen, weil die Events über Redis laufen.

Entscheidungen

Jede Karte hat eine Versionsnummer. Statt „Last Write Wins“ lehnt der Server Updates auf Basis einer alten Version ab. So überschreibt niemand still die Änderung eines Teammitglieds.

Der Login läuft über REST, das JWT wird beim Verbindungsaufbau des Sockets geprüft. Danach ist jede Verbindung auf die Boards beschränkt, zu denen der Nutzer gehört.

Der Redis-Adapter war von Anfang an dabei. Mit docker compose up --scale api=2 lässt sich zeigen, dass Clients auf verschiedenen Instanzen synchron bleiben. Cursor-Events werden gedrosselt, damit die Präsenzanzeige flüssig bleibt, ohne die Verbindung zu überlasten.