Ich arbeite an einer JSF-Webanwendung, deren Zweck darin besteht, ein Befehlszeilenprogramm zu umfassen. Eine ihrer Hauptfunktionen ist die Möglichkeit, eine Sitzung zwischen Benutzern zu teilen (z. B. für Kurse), sodass, wenn eine Eingabe an eine Instanz der Anwendung gesendet wird, die Ausgabe an jeden Abonnenten für diese Sitzung gesendet wird.
Als Ergebnis dieses Designs besteht die Webanwendung hauptsächlich aus einem view-scoped Bean, das einen Controller der Befehlszeilenanwendung anfordern wird. Es wurde auch gewählt, eine Sitzung mit dem URL-Fragment zu identifizieren (z. B. meine Domain / meine App / #SESSIONID), sodass jeder, der die URL mit dem gleichen Fragment verwendet, Eingaben und Ausgaben teilt, wobei er seine eigene Instanz des view-scoped-Beans verwendet, aber den gleichen Controller teilt
Um Ergebnisse an alle Abonnenten zu senden, verwende ich Primefaces Push. Die Ergebnisse sind in erster Linie Text, der an das Terminal der Webanwendung angehängt werden muss, aber einige Befehle führen zur programmatischen Erstellung eines JSF-Komponenten. Um dies zu handhaben, rendere ich diese Komponenten einfach zu einem String, den ich an alle Abonnenten sende.
Dann habe ich festgestellt, dass der zugehörige UIComponent hinzugefügt werden muss, um Ajax-Anfragen von Komponenten (und von jedem Abonnenten) zu verarbeiten, muss zur UIViewRoot hinzugefügt werden im Kontext von (weiß nicht, wie man das ausdrücken soll) jedem view-scoped-Bean.
Tatsächlich habe ich zuerst versucht, einen "gemeinsamen Container" (ein UIForm) an eine Eigenschaft des view-scoped-Beans zu binden, in dem ich die programmatisch erstellten Komponenten platzieren würde, aber ich musste offensichtlich das Huhn-und-Ei-Problem bewältigen, über das @BalusC in seinem Blog spricht, weil die Komponente bei jeder Ajax-Anfrage erneut hinzugefügt wurde. Das Setzen von javax.faces.PARTIAL_STATE_SAVING
auf false hat auch nicht geholfen (ich verwende MyFaces 2.2.5)
Also, als eine Art Workaround, wenn der Controller eine neue Komponente erstellen muss, fügt er im Wesentlichen die ID der Komponente den übertragenen Daten hinzu (in einem zu Json konvertierten HashMap), und alle Abonnenten werden (zurück) ein remoteCommand an ihre eigene Instanz des view-scoped-Beans auslösen, um den "gemeinsamen Container" von ihrer eigenen UIViewRoot aus zu aktualisieren.
Das funktioniert, aber mir gefällt diese Art und Weise nicht!
Also:
-
Wäre es möglich, diese Art von Sharing zwischen view-scope Beans (mit dem gleichen Namen), die in unterschiedlichen HTTP-Sitzungen gespeichert sind, zu handhaben? Ich beziehe mich auf diese Antwort von @BalusC... vielleicht durch Spielen mit
javax.faces.ViewState
- wäre das überhaupt möglich? -
Gibt es einen "magischen" Scope für mein derzeit view-scoped Bean, den ich verwenden könnte?
-
Sollte ich eher ein vollkommen anderes Design verwenden?
Danke!