Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java EE 7: Web Services

Was sind WebSockets und wie kann ein serverseitiger Endpoint aufgesetzt werden?

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Dieses Video erklärt, was WebSockets sind, bespricht den Kommunikationsansatz und zeigt, wie ein serverseitiger Endpoint mit Hilfe der Java EE 7 umgesetzt werden kann.

Transkript

WebSockets sind ein neuer Kommunikationsstandard. Dieser Kommunikationsstandard erlaubt es, dass Clients und Server viel effizienter miteinanderkommunizieren können, als dies in der Vergangenheit der Fall war. In der Java EE haben wir mit der Version sieben Unterstützung für WebSockets in Form der Java API for WebSockets bekommen. In diesem Video werden wir uns damit auseinandersetzen, wie wir WebSockets definieren können und was WebSockets überhaupt sind. Generell sind WebSockets eine plattformübergreifende Spezifikation. Diese Spezifikation ist dafür gedacht, eine Duplex-Kommunikation zwischen Webseiten und Applikationen zu ermöglichen. Duplex-Kommunikation besagt, dass die Kommunikation nicht nur vom Client zum Server aus stattfinden kann, sondern auch vom Server zum Client angestoßen werden kann. Genau letzterer Aspekt war in der Vergangenheit bisher nämlich nicht möglich, das HTTP-Protokoll sieht dies einfach nicht vor. In der Vergangenheit musste man, wenn man beispielsweise serverseitige Push-Benachrichtigungen implementieren wollte, das Ganze auf der Clientseite implementieren, indem man dort den sogenannten Client-Pull Ansatz genutzt hat. Dieser Client-Pull Ansatz ist im Grunde ein Ansatz, bei dem der Client in regelmäßigen Abständen beim Server nachfragt, ob es für ihn neue Nachrichten oder ähnliches gebe. Wenn dem so ist, wird der Server ihm das zurückliefern und der Client sorgt dann für die Anzeige dieser Information. Das Ganze ist allerdings ganz furchtbar unperformant, speziell für den Server, denn wenn einige Dutzend oder hundert Clients parallel anfragen und das auch noch in sehr kurzen Zeitabständen, dann erzeugen sie eine ganz gewaltige Last auf dem Server, die dieser erstmal natürlich überhaupt beherrschen muss. An der Stelle helfen WebSockets enorm, denn das Kommunikationsprotokoll erlaubt es, dass auch der Server seinerseits eine Verbindung mit den Clients aufrecht erhalten kann und diesen dann bei Bedarf eine Nachricht schicken kann. Das heißt, die ganzen Anfragen an den Server unterbleiben zukünftig. WebSockets werden von den großen Browsern in ihren aktuellen Versionen unterstützt. Die WebSockets API, mit der wir im Java EE Umfeld arbeiten können, ist definiert im JSR 356. Die Vorgehensweise beim Einsatz von WebSockets ist immer die gleiche. Der Server definiert einen Endpoint, also eine Stelle, mit der die Clients kommunizieren können, bei der sie sich registrieren können. Die Clients verbinden sich dann mit diesem Endpoint und anschließend können Nachrichten vom Client an den Server und vom Server an den Client versandt werden. Diese Nachrichten, die versendet werden können, sind entweder textuell oder binär. Wenn wir auf Ebene der Java EE einen WebSocket-Endpoint erzeugen wollen, haben wir zwei Ansätze zur Auswahl. Zum einen können wir das Ganze programmatisch machen, indem wir von der Basisklasse Endpoint erben und dann Methoden überschreiben. Die andere Herangehensweise und das ist die, die wir auch im Folgenden verwenden werden, ist das Ganze per Annotation zu machen. Dadurch sind wir nicht darauf festgelegt, dass bestimmte Methoden bestimmte Namen haben. Grundsätzlich werden vier Methoden oder Annotationen definiert. Zum einen die Methode onOpen(), beziehungsweise die @OnOpen Annotation. Eine damit gekennzeichnete Methode wird aufgerufen, wenn ein Client eine Verbindung zum Eine Methode, die mit @OnMessage annotiert ist, wird dann aufgerufen, wenn der Client eine Nachricht an den Server sendet. Tritt ein Fehler auf, wird die onError() Methode beim programmatischen Ansatz, beziehungsweise eine Methode mit der @OnError Annotation aufgerufen. Und wenn ein Client eine Verbindung schließt, dann wird, beim programmatischen Einsatz die Methode onClose() und beim Annotationseinsatz eine mit @OnClose annotierte Methode aufgerufen und dann können wir Aufräumarbeiten vornehmen. Wenn wir eine Nachricht versenden wollen, arbeiten wir mit einer sogenannten Session-Instanz. Diese Session-Instanz wird uns beim Herstellen der Verbindung übergeben, sie wird uns auch optional beim Aufrufen einer onMessage() Methode übergeben. Die Nachricht, die wir dann auf die eingehende Nachricht senden können, versenden wir direkt als Rückgabe der Methode oder wir nutzen eine Methode auf der Session-Instanz. Das ist kein Problem. Etwas schwieriger wird die ganze Angelegenheit jedoch, wenn wir einen Push machen wollen, wenn wir also eine Nachricht an mehrere Empfänger versenden wollen. In diesem Fall müssen wir eine Liste der Sessions selber vorhalten und dafür sorgen, dass diese Sessions dann entsprechend benachrichtigt werden. Nun werden wir, nach dieser ganzen Vorrede, einmal einen serverseitigen WebSocket implementieren. Ich habe hier bereits einmal ein Webprojekt angelegt. In diesem Webprojekt werden wir nun einen Endpoint hinterlegen. Wichtig ist: Derartige Endpoints liegen immer in einem Webprojekt und nicht etwa in einem EJB Projekt. Wir legen einfach eine neue Java Klasse an. Diese Klasse wird den Namen ChatEndpoint bekommen und sie liegt im Package de.video2brain.websockets. Es handelt sich um eine ganz normale Java Klasse. Diese Klasse werden wir nun mit der @ServerEndpoint Annotation versehen. Die @ServerEndpoint Annotation erfordert die Eingabe eines Pfades. Dieser Pfad muss immer mit einem Schrägstrich beginnen, weil er von der Wurzel der Webapplikation aus gesehen wird. Es ist bei Ihnen sehr wahrscheinlich, dass die Annotation ServerEndpoint im Moment noch nicht aufgelöst werden kann. Um dies zu erreichen, müssen Sie Ihrem Projekt einen Verweis auf die API der WebSocket-Implementierung bereitstellen. Wir machen dies, indem wir einen Rechtsklick auf unser Projekt ausführen und dann aus den Eigenschaften den Eintrag Properties auswählen. Hier können wir in dem Bereich Java Build Path wechseln und nun können wir im Bereich Libraries eine Bibliothek hinzufügen. Und zwar machen wir das, indem wir auf die Schaltfläche Add External JARs… klicken. Nun müssen wir in den Ordner unseres WildFly Application Servers wechseln und wechseln hier in den Unterordner modules, system, layers, base, javax, WebSocket, api, main und finden dann die API Spezifikation. Diese Spezifikation, also das entsprechende Java-Archiv, müssen wir unserem Projekt als Referenz hinzufügen und dann kann auch die @ServerEndpoint-Annotation aufgelöst werden. Nun können wir uns um die eigentliche Implementierung unseres Endpoints kümmern. Zunächst einmal lege ich eine private statische Variable an und die wird ein Set halten, aus dem Java Util Package und zwar ein Set vom Typ Session. Session muss unbedingt die Session aus dem javax.websocket Package sein. In diesem Set mit dem Namen Sessions halte ich nun alle Sessions, die von den Clients geöffnet werden. Das mache ich als ein synchronised Set mit Hilfe der Collections Hilfsklasse aus dem Java util Package. Dieses synchronised Set hält dann intern ein HashSet vom Typ Session. Das Ganze klingt ganz furchtbar umständlich und schwierig, hat aber letztlich den Sinn, dass wir alle Sessions, die aktiv sind, dann auch verwalten können und allen aktiven Sessions auch Nachrichten schicken können. Nun implementieren wir zunächst einmal die Methode, die aufgerufen wird, wenn ein Client eine Session öffnet. Der Name dieser Methode ist frei wählbar. Ich nenne sie opened und der Übergabeparameter ist eine Session. Diese Kleinsession merke ich mir in der Sessionsauflistung. Damit die Methode auch angesprochen wird, annotiere ich sie mit @OnOpen. Die nächste Methode, die ich benötige, nenne ich closed. Und auch hier bekommen wir eine Session-Instanz übergeben und das ist die Session, die geschlossen worden ist. Und nun entferne ich die Session aus der Liste der aktiven Sessions. Diese Methode annotiere ich mit @OnClose. Nun implementiere ich noch die Methode, die aufgerufen wird, wenn ein Client eine Nachricht an den Server sendet. Wie Sie dem Namen dieses Endpoints schon entnehmen können, möchte ich einen ServerEndpoint für einen Chat definieren, das heißt, ich möchte alle Sessions benachrichtigen, wenn eine neue Nachricht einkommt. Und genau das implementiere ich. Die Methode heißt Chat und hier bekomme ich zwei Parameter übergegeben. Zum einen die Session, die die Nachricht versendet hat und zum anderen die Nachricht, die versendet worden ist. Bevor ich fortfahre, annotieren ich diese Methode mit @OnMessage. Innerhalb dieser Methode durchlaufe ich nun alle Client Sessions, die sich innerhalb der Sessionsauflistung befinden. Und nun sende ich asynchron an die Clients eine Nachricht. Warum mache ich das asynchron? Damit es nicht blockiert. Ich kann das Ganze auch synchron machen, aber ich bevorzuge hier den asynchronen Weg, sodass in der Zwischenzeit auch weitere Chatnachrichten eingehen können, die dann entsprechend weiter versandt werden. Zu diesem Zweck rufe ich auf dieser Client Session die Methode getAsyncRemote() auf, damit kann ich asynchron versenden oder, wenn ich synchron versenden möchte, dann getBasicRemote. Ich benutze hier getAsyncRemote() und sende darüber die Nachricht einfach weiter. Das bedeutet, wenn eine Nachricht eingeht, werden sämtliche Clients diese Nachricht erhalten. Damit haben wir den serverseitigen WebSocket fertig implementiert. Nun können wir die Webapplikation starten und wenn wir schon einen Client hätten, der mit dieser Webapplikation interagieren würde, dann wäre es nunmehr möglich, dass man an dieser Stelle bereits Nachrichten austauschen könnte. In diesem Video haben wir uns damit auseinandergesetzt, wie wir einen serverseitigen Endpoint für WebSockets definieren können. Wir haben ebenfalls geklärt, was WebSockets überhaupt sind und wo ihre Vorteile gegenüber einer ganz normalen Kommunikation über HTTP liegen.

Java EE 7: Web Services

Steigen Sie ein in die Java-Enterprise-Welt und lernen Sie, wie Nachrichten ausgetauscht und Dienste definiert werden.

5 Std. 13 min (30 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!