Ich habe eine Webseite, auf der eine große Datenmenge vom Server angezeigt wird. Die Kommunikation erfolgt über Ajax.
Jedes Mal, wenn der Benutzer mit diesen Daten interagiert und sie ändert (sagen wir, Benutzer A benennt etwas um), weist er den Server an, die Aktion auszuführen, und der Server gibt die neuen geänderten Daten zurück.
Wenn Benutzer B gleichzeitig auf die Seite zugreift und ein neues Datenobjekt erstellt, teilt er dies dem Server erneut über Ajax mit, und der Server kehrt mit dem neuen Objekt für den Benutzer zurück.
Auf der Seite von A haben wir die Daten mit einem umbenannten Objekt. Und auf B's Seite haben wir die Daten mit einem neuen Objekt. Auf dem Server haben die Daten sowohl ein umbenanntes als auch ein neues Objekt.
Welche Möglichkeiten habe ich, um die Seite mit dem Server synchron zu halten, wenn mehrere Benutzer sie gleichzeitig verwenden?
Optionen wie das Sperren der gesamten Seite oder das Speichern des gesamten Status für den Benutzer bei jeder Änderung werden eher vermieden.
Wenn dies hilfreich ist, ruft die Webseite in diesem speziellen Beispiel eine statische Webmethode auf, die eine gespeicherte Prozedur in der Datenbank ausführt. Die gespeicherte Prozedur gibt alle geänderten Daten zurück und nicht mehr. Die statische Webmethode leitet dann die Rückgabe der gespeicherten Prozedur an den Client weiter.
Bounty Edit:
Wie entwerfen Sie eine Mehrbenutzer-Webanwendung, die Ajax für die Kommunikation mit dem Server verwendet, jedoch Probleme mit der Parallelität vermeidet?
Dh gleichzeitiger Zugriff auf Funktionen und Daten in einer Datenbank ohne das Risiko von Daten oder Statusbeschädigungen
Antworten:
Überblick:
Hallo Raynos,
Ich werde hier kein bestimmtes Produkt diskutieren. Was andere erwähnt haben, ist ein gutes Toolset, das Sie sich bereits ansehen sollten (fügen Sie möglicherweise node.js zu dieser Liste hinzu).
Aus architektonischer Sicht scheinen Sie das gleiche Problem zu haben, das in der Versionskontrollsoftware auftritt. Ein Benutzer checkt eine Änderung an einem Objekt ein, ein anderer Benutzer möchte dasselbe Objekt auf andere Weise ändern => Konflikt. Sie müssen Benutzeränderungen an Objekten integrieren und gleichzeitig in der Lage sein, Aktualisierungen zeitnah und effizient bereitzustellen und Konflikte wie die oben genannten zu erkennen und zu lösen.
Wenn ich in deinen Schuhen stecke, würde ich so etwas entwickeln:
1. Serverseitig:
Bestimmen Sie eine vernünftige Ebene, auf der Sie definieren würden, was ich als "atomare Artefakte" bezeichnen würde (die Seite? Objekte auf der Seite? Werte in Objekten?). Dies hängt von Ihren Webservern, Ihrer Datenbank- und Caching-Hardware, der Anzahl der Benutzer, der Anzahl der Objekte usw. ab. Dies ist keine einfache Entscheidung.
Für jedes atomare Artefakt gilt:
Ein Server oder eine Pseudo-Server-Komponente, die in der Lage ist, relevante Änderungsprotokolle effizient an einen verbundenen Benutzer zu senden. Observer-Pattern ist dein Freund dafür.
2. Client-Seite:
Ein Javascript-Client, der eine langjährige HTTP-Verbindung zu dem oben genannten Server herstellen kann oder Lightweight Polling verwendet.
Eine Javascript-Artefakt-Updater-Komponente, die den Inhalt der Site aktualisiert, wenn der verbundene Javascript-Client über Änderungen im Verlauf der beobachteten Artefakte informiert. (Auch hier könnte ein Beobachtermuster eine gute Wahl sein)
Eine Javascript-Artefakt-Committer-Komponente, die möglicherweise die Änderung eines atomaren Artefakts anfordert und versucht, eine Mutex-Sperre zu erhalten. Durch Vergleichen der bekannten clientseitigen Artefakt-Versions-ID und der aktuellen serverseitigen Artefakt-Versions-ID wird festgestellt, ob der Status des Artefakts wenige Sekunden zuvor von einem anderen Benutzer geändert wurde (Latanz des Javascript-Clients und Festschreibungsprozessfaktoren).
Ein Javascript-Konfliktlöser, der einem Menschen ermöglicht, welche Änderung die richtige Entscheidung ist. Möglicherweise möchten Sie dem Benutzer nicht einfach mitteilen, dass jemand schneller war als Sie. Ich habe Ihre Änderung gelöscht. Gehen Sie weinen. Viele Optionen aus eher technischen Unterschieden oder benutzerfreundlicheren Lösungen scheinen möglich zu sein.
Also wie würde es rollen ...
Fall 1: Art des Sequenzdiagramms zur Aktualisierung:
Fall 2: Jetzt zum Festschreiben:
Fall 3: für Konflikte:
Einige Worte zu Leistung und Skalierbarkeit
HTTP Polling vs. HTTP "Pushing"
Backend-Skalierung
Frontend-Skalierung
"kreative" Optimierungen
Nun, ich hoffe, dies kann ein Anfang für Ihre eigenen Ideen sein. Ich bin sicher, es gibt noch viel mehr Möglichkeiten. Ich freue mich über jede Kritik oder Verbesserung dieses Beitrags. Das Wiki ist aktiviert.
Christoph Strasen
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich dachte, ich würde mich einfach einmischen.
OT (Operational Transforms) scheinen gut zu Ihrer Anforderung für die gleichzeitige und konsistente Bearbeitung durch mehrere Benutzer zu passen. Diese Technik wird in Google Text & Tabellen verwendet (und wurde auch in Google Wave verwendet):
Es gibt eine JS-basierte Bibliothek für die Verwendung von Operational Transforms - ShareJS ( http://sharejs.org/ ), die von einem Mitglied des Google Wave-Teams geschrieben wurde.
Und wenn Sie möchten, gibt es ein vollständiges MVC-Webframework - DerbyJS ( http://derbyjs.com/ ), das auf ShareJS basiert und alles für Sie erledigt.
Es verwendet BrowserChannel für die Kommunikation zwischen dem Server und den Clients (und ich glaube, dass die Unterstützung von WebSockets in Arbeit sein sollte - es war zuvor über Socket.IO verfügbar, wurde jedoch aufgrund der Probleme des Entwicklers mit Socket.io entfernt). Anfängerdokumente sind a im Moment allerdings etwas spärlich.
quelle
Ich würde in Betracht ziehen, für jeden Datensatz einen zeitbasierten modifizierten Stempel hinzuzufügen. Wenn Sie also DB-Tabellen aktualisieren, würden Sie den geänderten Zeitstempel entsprechend ändern. Mit AJAX können Sie den geänderten Zeitstempel des Clients mit dem Zeitstempel der Datenquelle vergleichen. Wenn der Benutzer jemals zurückbleibt, aktualisieren Sie die Anzeige. Ähnlich wie diese Site eine Frage regelmäßig überprüft, um festzustellen, ob jemand andere sie beantwortet hat, während Sie eine Antwort eingeben.
quelle
Sie müssen Push-Techniken (auch als Comet oder Reverse Ajax bezeichnet) verwenden, um Änderungen an den Benutzer weiterzugeben, sobald sie an der Datenbank vorgenommen werden. Die derzeit beste verfügbare Technik hierfür scheint Ajax Long Polling zu sein, sie wird jedoch nicht von jedem Browser unterstützt, sodass Sie Fallbacks benötigen. Glücklicherweise gibt es bereits Lösungen, die dies für Sie erledigen. Darunter sind: orbited.org und das bereits erwähnte socket.io.
In Zukunft wird es einen einfacheren Weg geben, der als WebSockets bezeichnet wird. Es ist jedoch noch nicht sicher, wann dieser Standard zur Hauptsendezeit bereit sein wird, da Sicherheitsbedenken hinsichtlich des aktuellen Status des Standards bestehen.
Es sollten keine Parallelitätsprobleme in der Datenbank mit neuen Objekten auftreten. Wenn ein Benutzer ein Objekt bearbeitet, muss der Server über eine Logik verfügen, die prüft, ob das Objekt in der Zwischenzeit bearbeitet oder gelöscht wurde. Wenn das Objekt gelöscht wurde, ist die Lösung wieder einfach: Verwerfen Sie einfach die Bearbeitung.
Das schwierigste Problem tritt jedoch auf, wenn mehrere Benutzer gleichzeitig dasselbe Objekt bearbeiten. Wenn Benutzer 1 und 2 gleichzeitig mit der Bearbeitung eines Objekts beginnen, nehmen beide ihre Änderungen an denselben Daten vor. Angenommen, die von Benutzer 1 vorgenommenen Änderungen werden zuerst an den Server gesendet, während Benutzer 2 die Daten noch bearbeitet. Sie haben dann zwei Möglichkeiten: Sie können versuchen, die Änderungen von Benutzer 1 mit den Daten von Benutzer 2 zusammenzuführen, oder Sie können Benutzer 2 mitteilen, dass seine Daten veraltet sind, und ihm eine Fehlermeldung anzeigen, sobald seine Daten an den Server gesendet werden. Letzteres ist hier nicht sehr benutzerfreundlich, aber Ersteres ist sehr schwer zu implementieren.
Eine der wenigen Implementierungen, die dies zum ersten Mal wirklich richtig machten , war EtherPad , das von Google übernommen wurde. Ich glaube, sie haben dann einige der EtherPad-Technologien in Google Text & Tabellen und Google Wave verwendet, aber das kann ich nicht mit Sicherheit sagen. Google hat auch EtherPad geöffnet. Je nachdem, was Sie tun möchten, ist dies möglicherweise einen Blick wert.
Es ist wirklich nicht einfach, diese Dinge gleichzeitig zu bearbeiten, da es aufgrund der Latenz nicht möglich ist, atomare Operationen im Web durchzuführen. Vielleicht hilft Ihnen dieser Artikel , mehr über das Thema zu erfahren.
quelle
Der Versuch, all dies selbst zu schreiben, ist eine große Aufgabe, und es ist sehr schwierig, es richtig zu machen. Eine Möglichkeit besteht darin, ein Framework zu verwenden, mit dem Clients in Echtzeit mit der Datenbank und untereinander synchronisiert werden können.
Ich habe festgestellt, dass das Meteor-Framework dies gut macht ( http://docs.meteor.com/#reactivity ).
"Meteor unterstützt das Konzept der reaktiven Programmierung. Dies bedeutet, dass Sie Ihren Code in einem einfachen imperativen Stil schreiben können. Das Ergebnis wird automatisch neu berechnet, wenn sich Daten ändern, von denen Ihr Code abhängt."
"Dieses einfache Muster (reaktive Berechnung + reaktive Datenquelle) hat eine breite Anwendbarkeit. Der Programmierer kann keine Abmelde- / Abmeldeaufrufe schreiben und sicherstellen, dass sie zum richtigen Zeitpunkt aufgerufen werden, wodurch ganze Klassen von Datenverbreitungscode eliminiert werden, die sonst Ihre Daten verstopfen würden Anwendung mit fehleranfälliger Logik. "
quelle
Ich kann nicht glauben, dass niemand Meteor erwähnt hat . Es ist sicher ein neues und unausgereiftes Framework (und unterstützt offiziell nur eine Datenbank), aber es erfordert die ganze Arbeit und das Denken einer Mehrbenutzer-App, wie sie auf dem Poster beschrieben wird. Tatsächlich können Sie KEINE Live-Aktualisierungs-App für mehrere Benutzer erstellen. Hier ist eine kurze Zusammenfassung:
Meteor ist so einfach, dass ich vorschlagen würde, dass Sie es sich zumindest ansehen, um Ideen zu stehlen.
quelle
Diese Wikipedia-Seiten können dazu beitragen, das Erlernen von Parallelität und Concurrent Computing für das Entwerfen einer Ajax- Webanwendung , die EDA- Nachrichten ( State State Event ) in einem Messaging-Muster abruft oder gepusht wird , zu erweitern . Grundsätzlich werden Nachrichten an Kanalteilnehmer repliziert, die auf Änderungsereignisse und Synchronisationsanforderungen reagieren.
Es gibt viele Formen gleichzeitiger webbasierter Software für die Zusammenarbeit .
Es gibt eine Reihe von HTTP-API-Clientbibliotheken für etherpad-lite , einen kollaborativen Echtzeiteditor .
django-realtime-playground implementiert eine Echtzeit-Chat-App in Django mit verschiedenen Echtzeit-Technologien wie Socket.io .
Sowohl AppEngine als auch AppScale implementieren die AppEngine Channel API . Dies unterscheidet sich von der Google Realtime API , die durch googledrive / realtime-playground demonstriert wird .
quelle
Serverseitige Push- Techniken sind hier der richtige Weg. Komet ist (oder war?) Ein Modewort.
Welche Richtung Sie einschlagen, hängt stark von Ihrem Server-Stack ab und davon, wie flexibel Sie sind. Wenn Sie können, würde ich einen Blick auf socket.io werfen , das eine browserübergreifende Implementierung von Websockets bietet, die eine sehr optimierte Möglichkeit für die bidirektionale Kommunikation mit dem Server bietet und es dem Server ermöglicht, Aktualisierungen an die Clients zu senden.
Sehen Sie sich insbesondere diese Demonstration des Autors der Bibliothek an, die fast genau die von Ihnen beschriebene Situation zeigt.
quelle