Speichern während der Zusammenarbeit in Echtzeit

10

Ich möchte, dass mehrere Benutzer dasselbe Dokument bearbeiten. Das Problem besteht darin, dass ein neuer Benutzer beim Beitritt möglicherweise ein veraltetes Dokument sieht. Wie stelle ich sicher, dass neue Benutzer die neuesten Änderungen erhalten?

Einige Lösungen, an die ich gedacht habe:

  • Sparen Sie bei jeder Änderung. Ich mag diese Lösung nicht, weil sie die Benutzeroberfläche verlangsamt und die Datenbank belastet.

  • Wenn ein neuer Benutzer beitritt, lösen Sie das Speichern auf allen anderen Clients aus. Laden Sie das Dokument, nachdem andere Clients es gespeichert haben. Damit kann es immer noch zu Inkonsistenzen kommen.

Alle anderen Vorschläge wären hilfreich.

UPDATE: Nachdem ich mir die vorgeschlagene Lösung, die Google Realtime API, angesehen hatte, stellte ich fest, dass:

  1. Benutzer Ihrer App müssen über Google Drive verfügen und Ihnen Zugriff auf ihr Laufwerk gewähren . Dies könnte bestenfalls einen unangenehmen Ablauf der Benutzeroberfläche darstellen oder verhindern, dass Benutzer ohne Google Drive die Echtzeitfunktion verwenden.

  2. Alle Freigabeeinstellungen, die auf Ihrer Seite vorgenommen werden, müssen für das Google-Dokument repliziert werden.

UPDATE 2: Um das Ziel zu erreichen, habe ich mich für Googles Firebase entschieden

Entwickler
quelle
Warum gibt es einen Unterschied zwischen einem neuen Benutzer und bereits aktiven Benutzern, die dasselbe Dokument bearbeiten / anzeigen?
Andy
@Andy Was ich gerade mache, ist das Senden aller Änderungen, die Benutzer vornehmen, über Sockets. Diese Änderungen aktualisieren die Benutzeroberfläche für Benutzer, deren Browser geöffnet sind, die jedoch nicht sofort in der Datenbank gespeichert werden. Ich habe also die Situation, dass ein neuer Benutzer, der beitritt, ein Dokument aus der Datenbank lädt und nicht alle letzten Änderungen sieht, die noch nicht gespeichert wurden.
dev.e.loper
1
Wenn Sie bereits Änderungen senden und das gleiche Verhalten wie jetzt beibehalten möchten, können Sie einen der Clients bitten, die letzte Ansicht an einen neuen Client zu senden, oder Sie können einen virtuellen Client auf dem Server haben, der alle Änderungen erhält und wenn ein neuer Client beitritt, spätestens sendet Blick darauf.
Dainius

Antworten:

14

Google Drive

Wenn Sie versuchen, eine eigene Version von Google Docs zu erstellen, sollten Sie sich die Google Realtime-API ansehen . Google hat dies kürzlich veröffentlicht, um anderen Entwicklern die Verwendung derselben Tools zu ermöglichen, die sie für die Zusammenarbeit in Echtzeit verwendet haben. Auf diese Weise können Sie Zeit bei Ihrer Entwicklung sparen und schneller ein funktionierendes Produkt erhalten.

Sie können die im Dokument enthaltenen Daten problemlos in regelmäßigen Abständen in Ihre Datenbank übertragen oder die Datenbank selbst als "Teilnehmer" des Austauschs verwenden, indem Sie einfach alle Änderungen abhören und protokollieren. Außerdem kann ein Benutzer seine eigenen Datenstrukturen definieren, die dann in der Echtzeit-API verwendet werden können, sodass Sie sie nach Belieben erweitern können.

Nicht von Google Drive

Nach Ihren Recherchen ist Google Drive also keine Option. Das ist in Ordnung, aber es wird schwieriger und funktioniert möglicherweise nicht so gut, je nachdem, wie viel Sie in es stecken.

Hier ist eine allgemeine Strategie, mit der ich dieses Problem lösen würde:

  1. Der Server soll der Kommunikationsmultiplexer sein. Jede Person spricht mit dem Server und der Server sendet diese Informationen an alle anderen. Auf diese Weise hat der Server immer die aktuellste Ansicht des Dokuments.

  2. Suchen Sie einen Algorithmus / ein Modul eines Drittanbieters zur Konfliktlösung. Konfliktlösung ist schwierig und immer noch nicht perfekt. Dies allein könnte den Umfang des Projekts leicht vergrößern, um viel zu groß zu sein. Wenn Sie keinen Algorithmus eines Drittanbieters verwenden können, würde ich vorschlagen, dass Sie nur einem Benutzer erlauben, einen Bereich einer Zeit zu bearbeiten, sodass der Benutzer vor dem Bearbeiten eines Bereichs eine Sperre erhalten muss, oder Sie riskieren, die Arbeit eines anderen Benutzers zu zerstören wird sehr alt, sehr schnell.

  3. Wenn ein neuer Benutzer beitritt, geben Sie ihm das neueste Dokument und streamen Sie die Befehle automatisch an ihn. Der Server hat die aktuellste Ansicht und kann diese daher automatisch austeilen.

  4. Sicherung in der Datenbank in bestimmten Intervallen. Entscheiden Sie, wie oft Sie eine Sicherungskopie erstellen möchten (alle 5 Minuten oder möglicherweise alle 50 Änderungen). Auf diese Weise können Sie die gewünschte Sicherung beibehalten.

Probleme: Dies ist keine perfekte Lösung. Hier sind einige Probleme, mit denen Sie möglicherweise konfrontiert sind.

  1. Der Durchsatz des Servers kann die Leistung beeinträchtigen

  2. Zu viele Leute, die lesen / schreiben, können den Server überlasten

  3. Personen gehen möglicherweise nicht mehr synchron, wenn eine Nachricht verloren geht. Sie sollten daher sicherstellen, dass Sie an regelmäßigen Punkten synchronisieren. Dies bedeutet, dass die gesamte Nachricht erneut gesendet werden muss, was kostspielig sein kann. Andernfalls verfügen die Benutzer möglicherweise nicht über dasselbe Dokument und kennen es nicht.

Ampt
quelle
Ja, die Änderungen werden an alle Clients gesendet und sie haben ihre (hoffentlich gleiche) Version im Browser. Klingt so, als würden Sie sagen, dass das Aktualisieren des Dokuments bei jeder Aktion ein guter Weg ist?
dev.e.loper
Oder haben Sie zumindest regelmäßige Synchronisierungszeiträume, in denen der aktuelle Status des Dokuments im Hintergrund übertragen wird, um sicherzustellen, dass sich alle auf derselben Seite befinden. Wie oft würde davon abhängen, wie schnell die Leute das Dokument ändern würden. Auf diese Weise haben Sie bereits eine etablierte Methode zum Senden an neue Personen sowie die Möglichkeit, sicherzustellen, dass diese niemals zu stark voneinander abweicht.
Ampt
1
+1. Mach das Leben nicht schwer. Google macht das gut, ohne das Rad neu erfinden zu müssen.
Neil
Speichert Google Realtime in Google Drive? Ich möchte in meiner Datenbank speichern, nicht in Google Drive.
dev.e.loper
@ dev.e.loper hat der Antwort für Sie einige Informationen dazu hinzugefügt.
Ampt
3

Ich würde 1 dauerhafte Kopie des Dokuments auf dem Server empfehlen. Wenn ein Client eine Verbindung zum Server herstellt, geben Sie UPDATEdiesem Client einen Befehl mit allen Änderungen aus.

Aktualisieren Sie WorkFlow

Der Benutzer löst eine Änderung aus -> Client sendet UPDATEan Server -> Server sendet UPDATEan Clients

Lebensfähige Auslöser

  1. Benutzer klickt auf Speichern
  2. Der Benutzer führt eine bestimmte Aufgabe aus
    • Beendet die Bearbeitung einer Zelle
    • Beendet die Bearbeitung eines Satzes / Absatzes / einer Zeile
  3. Benutzer klickt auf Rückgängig
  4. Benutzer drückt die Eingabetaste
  5. Der Benutzer gibt einen Schlüssel ein (bei jeder Änderung speichern)

Implementierung aktualisieren

Ich würde vorschlagen, das Dokument mit einer Reihe von UPDATEBefehlen neu erstellen zu können, damit der Server jedes UPDATE speichert. Wenn ein neuer Client eine Verbindung herstellt, kann dem Client eine Reihe von Aktualisierungen gesendet werden, und er selbst kann das anzuzeigende Dokument neu erstellen der Benutzer. Alternativ können Sie auch einen SAVEseparaten Befehl verwenden und UPDATE als temporäre Änderungen verwenden, die für UNDOAnforderungen verwendet werden können. SAVE speichert ihn tatsächlich, um ihn erneut zu öffnen, wenn der Server geschlossen wird oder alle Clients die Verbindung trennen.

Korey Hinton
quelle
2
Was ist mit Konfliktlösung? Was ist, wenn zwei Personen gleichzeitig denselben Textbereich bearbeiten? Dies scheint auch eine Belastung für die Datenbank zu sein, was OP vermeiden wollte. Es könnte für das, was er braucht, lebensfähig sein.
Ampt
@Ampt Ich habe mit diesem Modell eine Tabelle erstellt und bei Konflikten wurde jede zu aktualisierende Aufgabe vollständig durch die neueste Version ersetzt. Die letzte Person, die die Bearbeitung einer Zelle abgeschlossen hat, würde die zuvor aktualisierte Zelle ohne Zusammenführung vollständig ersetzen.
Korey Hinton
1
Ein Satz würde also einen anderen überschreiben, wenn dies beispielsweise ein Word-Dokument wäre?
Ampt
@Ampt ja, alternativ könnten Sie eine Methode implementieren, um zu sperren, woran gearbeitet wird, aber ich habe den einfachen Weg eingeschlagen.
Korey Hinton
3

1) Schauen Sie sich Knockout.js an

Es folgt einem MVVM-Muster und sendet basierend auf Änderungen am Modell automatisch Benachrichtigungen an die Ansicht. Schauen Sie sich zum Beispiel das beobachtbare Array an, um ein wenig mehr Informationen darüber zu erhalten, wie sie das tun.

2) Mischen Sie dies mit SignalR und Sie sollten nun die Möglichkeit haben, Benachrichtigungen an andere Benutzer zu senden, die an dem Dokument arbeiten. Von ihrer Website:

SignalR bietet außerdem eine sehr einfache API auf hoher Ebene, mit der Sie Server-zu-Client-RPC (JavaScript-Funktionen in den Browsern Ihrer Clients über serverseitigen .NET-Code aufrufen) in Ihrer ASP.NET-Anwendung ausführen und nützliche Hooks für das Verbindungsmanagement hinzufügen können , z. B. Ereignisse verbinden / trennen, Verbindungen gruppieren, Autorisierung.

Daher müssen Sie in Knockout.js einige Hooks auf Modellebene haben, um bei jeder Änderung einige SignalR-Aufrufe durchführen zu können. Die anderen Clients erhalten die Benachrichtigung von SignalR und lösen dann eine entsprechende Änderung in ihrer Kopie des Modells aus, die auf ihre Ansicht zurückgesetzt wird.

Es ist eine interessante Kombination der beiden Frameworks, und Sie sollten in der Lage sein, mehr Informationen zu suchen und zu sammeln, um mit den Details umzugehen.

In diesem Beispiel für ein Codeprojekt wird beispielsweise speziell angesprochen, Co Working UIs and Continuous Clientswas genau das zu sein scheint, was Sie versuchen.

New Age-Webanwendungen müssen möglicherweise New Age-Benutzererfahrungen bieten - und sollten mit kooperierenden und kontinuierlichen Client-Szenarien ordnungsgemäß umgehen. Dazu muss sichergestellt werden, dass die Benutzeroberfläche geräte- und benutzerübergreifend ordnungsgemäß synchronisiert wird, um sicherzustellen, dass der Status der Anwendung und der Benutzeroberfläche "wie sie sind" beibehalten wird.

Dieser Blog-Beitrag scheint ein Einstiegspunkt in eine Reihe von Blog-Beiträgen zu sein, in denen die Verwendung der beiden Pakete erörtert wird, und stellt dies einem herkömmlichen ASP.NET-Ansatz gegenüber. Kann einige Punkte berücksichtigen, die beim Entwerfen Ihrer Website berücksichtigt werden müssen.

Dieser Blog-Beitrag scheint etwas grundlegender zu sein und bietet die Grundlage für die Kombination der beiden Pakete.

Offenlegung: Ich bin weder mit einem der oben genannten Links verbunden, noch habe ich mich wirklich mit deren Inhalten befasst, um zu sehen, wie solide oder korrekt sie sind.


quelle
2

Die Lösung ist Operational Transformation (OT). Wenn Sie noch nichts davon gehört haben, ist OT eine Klasse von Algorithmen, die Echtzeit-Parallelität an mehreren Standorten durchführen. OT ist wie Echtzeit-Git. Es funktioniert mit jeder Verzögerung (von Null bis zu einem längeren Urlaub). Damit können Benutzer gleichzeitig Live-Änderungen mit geringer Bandbreite vornehmen. OT bietet Ihnen eine eventuelle Konsistenz zwischen mehreren Benutzern ohne erneute Versuche, ohne Fehler und ohne dass Daten überschrieben werden.

Die Implementierung von OT ist jedoch eine schwierige und zeitaufwändige Aufgabe. Vielleicht möchten Sie eine externe Bibliothek wie http://sharejs.org/ verwenden .

aj_
quelle
1
Die Google Realtime API führt OT youtu.be/hv14PTbkIs0?t=14m20s aus. Sie tun dies sowohl auf dem Client als auch auf dem Server. Ich konnte beim Lesen von ShareJS-Dokumenten keine klare Antwort erhalten, gehe aber davon aus, dass ShareJS OT sowohl auf dem Client als auch auf dem Server ausführt.
dev.e.loper
1

Dies hängt hauptsächlich von der Art Ihrer Dokumente und der Zusammenarbeit Ihrer Benutzer ab.

Ich würde jedoch:

  1. Lassen Sie alle Clients von Zeit zu Zeit nicht gespeicherte Änderungen an den Server senden (abhängig davon, wie Benutzer mit den Dokumenten arbeiten).
  2. Der Server speichert die Deltas in der Sitzung des Benutzers (selbst für einen fetten Client benötigen Sie so etwas wie eine Sitzung).
  3. Andere Clients, die dasselbe Dokument bearbeiten / anzeigen, erhalten diese vorübergehenden Änderungen oder zumindest einen Hinweis darauf, dass dies möglicherweise der Fall ist.

Vorteile:

  • Keine DB-Updates, es sei denn, jemand klickt auf "Speichern".
  • Backup für den Fall, dass der Client abstürzt (für den Sitzungszeitraum)
  • Ihr Server entscheidet, wie und welche Daten an welchen Client weitergeleitet werden sollen (z. B. können Sie die Funktion mit nur einer Notiz starten und später eine komplexere Zusammenführung und Hervorhebung implementieren).

Nachteile:

  • nicht 'Echtzeit' - zB senden Sie alle 30 Sekunden, aber jemand gibt in dieser Zeit 3 ​​Sätze ein.
  • Mehr Netzwerkverkehr - abhängig von Ihren Dokumenten und Ihrer Zusammenarbeit
  • möglicherweise große Sitzungen
  • Möglicherweise hoher Rechenaufwand, wenn viele Benutzer zusammenarbeiten und viele Änderungen vornehmen
Andy
quelle
1

Im Wesentlichen fragen Sie, wie Sie mit dem gemeinsamen veränderlichen Zustand umgehen sollen. Sparen ist der einfache Teil; Aber wie gehen Sie mit mehreren Personen um, die gleichzeitig dasselbe bearbeiten? Sie möchten, dass alle Benutzer dasselbe Dokument anzeigen und gleichzeitig die Bearbeitungen in Echtzeit synchronisieren.

Wie Sie wahrscheinlich gesehen haben, ist es ein schweres Problem! Es gibt einige pragmatische Lösungen:

  1. Ändern Sie Ihre Anwendungsanforderungen so, dass keine echte gleichzeitige Bearbeitung möglich ist. Änderungen können wie bei Versionsverwaltungssystemen zusammengeführt werden, wobei die Ergebnisse an jeden Client gesendet werden. Sie könnten dies selbst erstellen, aber es wäre eine schlechtere Benutzererfahrung.
  2. Lagern Sie die Synchronisation von Zustandsmutationen an eine Open-Source-Lösung aus, die sich in Ihre vorhandene Technologie integrieren lässt. ShareDB ist derzeit führend in diesem Bereich. Es basiert auf Operational Transformation und wird in mindestens einem Produktionssystem verwendet. Diese kümmert sich um die rettende Problem , das Sie mit sind besorgt , aber wird nicht helfen , mit einem der zusätzlichen UX verfügt zwingend für jede kollaborative Anwendung.
  3. Verwenden Sie eine Standardplattform wie Convergence (Haftungsausschluss: Ich bin Gründer), um alle schwierigen Aufgaben für Sie zu erledigen. Sie erhalten außerdem zusätzliche Tools für die Zusammenarbeit in Echtzeit, z. B. Cursor- / Mausverfolgung, Auswahl und Chat, um schnell eine überlegene Zusammenarbeit zu ermöglichen. In dieser Frage finden Sie eine gute Zusammenfassung aller vorhandenen Tools.
Alalonde
quelle