This page (revision-41) was last changed on 04-Sep-2014 13:44 by Dieter Käppel

This page was created on 21-Aug-2013 14:14 by Dieter Käppel

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
41 04-Sep-2014 13:44 35 KB Dieter Käppel to previous

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 1 changed one line
Das Produkt [JSF Ext] enthält eine ganze Reihe von JSF-Tags. Diese werden auf dieser Seite beschrieben.
Das Produkt [JSF Ext] enthält eine ganze Reihe von JSF-Tags. Diese werden auf dieser Seite beschrieben. die Tags für AJAX-Push sind in [JSF Ext Push] beschrieben.
At line 497 removed 134 lines
!!!AJAX Push
Mit sogenannten Push können Informationen aktiv an den Browser übertragen werden. Vor allem ist es dadurch möglich, eine Vielzahl von Benutzern gleichzeitig über ein Ereignis zu informieren.
Der Tag <e:socket> nutzt Web-Sockets um Browser-Push durchzuführen. Dies ist eine sehr effiziente Implementierung mit geringer Verzögerung zwischen dem Versenden der Nachricht und dem Eintreffen im Browser, sowie Netzwerk und Ressourcen schonend. Dies ist möglich, wenn der Web-Server den Web-Standard 3.0 beherrscht (z.B. ab Tomcat 7). Sind Web-Sockets nicht verfügbar aufgrund eines Web-Servers kleiner als 3.0, weil der Browser dies nicht beherrscht oder ein dazwischen liegender Proxy es nicht unterstützt, wird die Comet-Engine verwendet, die Long-Polling durchführt.
Dazu ist folgende Dependency zum Projekt hinzuzufügen:
{{{
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.1.0-beta1</version>
</dependency>
}}}
!!Push-Tag
Der Push-Tag ist die einfachste Art, AJAX-Push zu implementieren. Der Tag <e:push> stellt eine transparente Verbindung zu einem Push-Channel her. Der Inhalt des Tags wird auf alle Clients verteilt, die mit dem gleichen Channel verbunden sind:
{{{
<h:form id="form">
<h:commandButton value="Senden" action="#{pushTest.action}">
<f:ajax render=":test:value"/>
</h:commandButton>
</h:form>
<e:push id="test" direct="true">
<h:panelGrid id="panel" columns="2">
<h:outputText id="text" value="Test"/>
<h:outputText id="value" value="#{pushTest.count}"/>
</h:panelGrid>
</e:push>
}}}
__Erklärung:__ Der Tag ":test:value" wird durch eine einfache AJAX-Render-Anweisung auf allen verbundenen Clients neu gerendert.
!Direct- und AJAX-Mode
Der Push-Tag kann in zwei unterschiedlichen Modi betrieben werden: Direct und AJAX:
||Eigenschaft||Direct Mode||AJAX Mode
||Rendering|Inhalt wird nur bei dem Client gerendert, der den Event ausgelöst hat|Inhalt wird für jeden Client gerendert
||Effizienz|Effizienter Modus, da das HTML-Update direkt an alle Clients geschickt werden kann|Rendering wird für jeden Client getrennt gerendert
||Inhalt|Inhalt ist für jeden Client identisch|Inhalt kann für jeden Client individualisiert werden
||Daten|Anzeige von Daten die für mindestens eine Gruppe bestimmt oder öffentlich ist|Anzeige privater Daten möglich
||Auslöser|Auslöser ist ein Faces-Event|Auslöser kann ein Faces-Event, Timer oder beliebiger anderer Event sein
!Rendering
Die beim Render-Attribut angegebenen Ids werden einzeln gerendert und nur der relevante Inhalt zum Client übertragen. Auch wenn sich innerhalb des Push-Tag große Mengen an Tags befinden, wird nur die relevante Änderung übertragen, sofern die Render-Anweisungen entsprechend ausgelegt sind.
Damit ist es beispielsweise möglich, eine Tabelle zu erzeugen und einzelne Zellen per Push upzudaten.
!Channel
Wird der Channel-Attribut nicht angegeben, wird die Client-Id der Component als Channel benutzt.
__Warnung:__ Channel-Name und Push-Tag sollte für alle Clients übereinstimmen, damit die Inhalte übereinstimmen. Andernfalls kommt es zu sogenannten Cross-Talking - der Inhalt des Push-Tags ändert sich.
!!Socket-Tag
Mit dem Socket-Tag ist eine fortgeschrittenere Integration von AJAX-Push in die Applikation möglich. Dazu wird einfach ein sogenannter Socket in die XHTML-Seite gesetzt:
{{{
<e:socket channel="/test">
<f:ajax render=":push-form:chat"/>
</e:socket>
}}}
Auf der Java-Seite wird der Socket dann so angesprochen:
{{{
PushContext.instance().push("/test");
}}}
__Hinweis:__ In vielen Fällen reicht die reine Benachrichtigung des Client aus, weil dieser dann per AJAX-Call eine Server-Anfrage startet. Dies bietet den Vorteil, dass die Session und der FacesContext des entsprechenden Benutzers verfügbar ist.
Die Socket-Component unterstützt folgende Attribute und Behaviors:
||Attribut||Beschreibung
|channel|Das Attribut wird benötigt und beschreibt den Kommunikationskanal zum Server. Indem der Server diesen Channel informiert, wird im Browser eine Nachricht ausgeliefert. Die Besonderheit am Channel ist, dass dieser von beliebig vielen Browsern d.h. eingeloggten Benutzern abonniert werden kann. Der Server braucht daher nicht zu wissen, wieviele Clients überhaupt die Nachricht empfangen werden.
|onopen|Der Event wird beim Öffnen des Channels ausgelöst. Der Client weiß so immer, ob er verbunden ist oder nicht. Dadurch kann dem Nutzer auch ein Verbindungsstatus angezeigt werden.
|onclose|Das Gegenstück zu onopen, wird aufgerufen, wenn die Verbindung abbricht. Im normalen Produktivbetrieb wird diese Methode nur in Ausnahmefällen aufgerufen.
|onmessage|Dies ist der eigentliche Push-Aufruf. Wenn am Server PushContext.push() aufgerufen wird, wird am Client dieses JavaScript-Behavior ausgelöst.
|onerror|Hier kann eine Fehlerbehandlung hinzugefügt werden, zum Beispiel dem Benutzer angezeigt werden, wenn ein Problem mit der Verbindung auftaucht.
!!Push-Context
Auf der Server-Seite gibt es die Klasse com.intersult.jsf.push.PushContext. Um eine Nachricht zu einem Tag <e:socket channel="/test"> zu schicken, wird hier ein entsprechender Methodenaufruf durchgeführt:
{{{
PushContext.instance().push("/test");
}}}
!!Push-Parameter
Optional kann der Aufruf auch mit einem Parameter erfolgen, der wird dann JSON-Serialisiert und an den Client übertragen:
{{{
PushContext.instance().push("/test", parameter);
}}}
Auf der Client-Seite kann der Parameter dann wie folgt entgegen genommen werden:
{{{
<e:socket channel="/test" onmessage="alert(response.responseBody);">
}}}
!!Load Balancer und Reverse Proxy
Wird ein Load-Balancer verwendet, sind die Web-Sockets zu beachten. Bei Apache werden folgende Proxy-Einträge vor der eigentlichen Applikation gebraucht:
{{{
ProxyPass /<context-path>/faces/javax.faces.resource/<channel> ws://<ziel>/<context-path>/faces/javax.faces.resource/<channel>
ProxyPassReverse /<context-path>/faces/javax.faces.resource/<channel> ws://<ziel>/<context-path>/faces/javax.faces.resource/<channel>
}}}
__Erklärung:__ Die Web-Socket-Protokolle WS werden vor den eigentlichen Proxy-Einträgen für die Application abgefangen und mit dem WS-Protokoll umgeleitet. In Apache 2.4 steht dafür das Modul mod_proxy_wstunnel.so zur Verfügung.
!!!Resource-Tag
JSF-Resources können mit <h:outputStylesheet> und <h:outputScript> ausgegeben werden, mit <h:graphicImage> als Image angezeigt. Einige weitere Tags unterstützen die Attribute "name" und "library". Darüber hinaus gibt es die Möglichkeit, Resource-URLs mit
{{{
#{resource['<library>:<name>']}
}}}
zu erzeugen oder ganz zu Fuß mit
{{{
#{request.contextPath}/faces/javax.faces.resource/<name>?ln=<library>
}}}
Möchte man einen Link erzeugen vom Schema <a href="...">, bietet [JSF Ext] eine schönere Lösung:
{{{
<e:resourceLink name="<name>" library="<library">
<h:outputText value="Some link"/>
</e:resourceLink>
}}}
__Hinweis:__ Wie der normale <h:outputLink> unterstützt <h:resourceLink> ebenfalls Parameter vom Typ <f:param> (und abgeleitete Parameter wie <f:method-param> und <f:new>).