mercredi 18 juin 2014

WebSocket, et comment on teste?

On a vu comment implémenter des websockets avec SimpleWeb4j dans un précédant article, nous allons maintenant voir comment tester de manière automatisée la partie serveur websocket.


Librairies tierces

Pour garder un code relativement propre, je vais utiliser trois librairies :


Je veux faire quoi comme test?

Je cherche à tester le code du billet précédant qui, pour rappel, était un système de chat. Le serveur de websocket reçoit donc des messages qu'il redistribue à tous les clients connectés.

Scénario de test :

  • Ouverture d'une session 1.
  • Envoi d'un message par la session 1 (message 1).
  • Ouverture d'une session 2.
  • Envoi d'un message par la session 2 (message 2).
  • Envoi d'un message par la session 1 (message 3).
  • Fermeture de la session 1.
  • Envoi d'un message par la session 2 (message 4).
  • Fermeture de la session 2.

Vérifications à faire :

  • La session 1 a reçu 3 messages (les messages 1 à 3)
  • La session 2 a reçu 3 messages (les messages 2 à 4)


Code de test

Assez parler, place au code. J'espère que les commentaires sont suffisants, si ce n'est pas le cas, n'hésitez pas à le dire j'en ajouterais.

mercredi 11 juin 2014

WebSocket et SimpleWeb4j

Nous allons voir comment faire du websocket avec SimpleWeb4j.

WebSocket c'est quoi

WebSocket est un protocole permettant la communication de type push entre un browser et un serveur de manière bi-directionnelle.


On fait quoi comme exemple?

Comme je suis super original, on va partir sur un chat (le truc pour discuter, pas l'animal !), ça nous rappellera la grande époque de caramail :)

Pour mettre en place un chat, on a besoin d'un service côté serveur qui peut recevoir des messages en push depuis les clients, et quand il en reçoit un le redistribue à tous les clients.


La partie serveur

Nous allons commencer par créer notre objet métier représentant un message, celui-ci contient l'utilisateur, le texte et la date du message. Il servira pour les messages que l'on envoie aux clients (pour les flux client -> serveur, nous utiliserons une simple String).

Nous allons maintenant créer la route de la websocket avec la méthode SimpleWeb4j.websocket, cette méthode prend en paramètre une String représentant l'url et un WebSocketAdapter. Un WebSocketAdapter et une factory qui contient une méthode prenant en paramètres les "RouteParameters" et qui construit un WebSocketListenner. On a donc le code suivant pour l'instant :

Voyons maintenant comment construire le "WebSocketListener", nous avons pour ça un builder. Nous souhaitons construire un listener en implémentant un comportement sur 3 événements :

  • onConnect : on ajoute la session dans un set pour connaître les sessions ouvertes.
  • onClose : on supprime la session de notre set.
  • onMessage : on envoi le message reçu à tout les clients.
Voici donc le résultat final :


La partie cliente

Pour la partie cliente, on a un objet javascript "WebSocket" qui prend l'url en paramètre du constructeur.

Il nous reste après à définir les callback "onmessage" et "onopen". Pour envoyer un message au serveur, il suffit d'utiliser la méthode WebSocket.send. Si vous voulez plus de détails, vous pouvez aller voir la page de mozilla.

Voici donc la page html complète, comme d'habitude, j'utilise angular.js :) >/p>

Alors, ça vous parait compliqué de faire du WebSocket?

vendredi 6 juin 2014

La fin d'un article par jour

Le dernier article de la semaine sera consacré à vous dire que j'arrête d'écrire tous les jours!

Les raisons :

  • La fréquentation de blog (entre 10 et 30 utilisateurs par jour)
  • La baisse de la fréquentation par article depuis que j'écris tous les jours
  • Le manque d'idée pour continuer à tenir ce rythme :)

N'hésitez pas à me faire vos retours sur cette expérience qui a duré 2 semaines.

Je ne vais pas pour autant retourner à un article par an, mais plutôt un article par semaine.

Bon WE!

jeudi 5 juin 2014

Server Sent Events, et côté client?

Aujourd'hui, je vais vous parler de Server Sent Events côté client javascript.

Nous allons reprendre le serveur qui envoyait l'heure toutes les secondes codé ici.

L'utilisation d'un flux Server Sent Event se fait par l'intermédiaire de l'objet "EventSource" qui prend comme paramètre dans le constructeur l'url du flux. Cet objet possède une fonction "addEventListener" qui prend en paramètres le type de listener (message pour la réception de nouvelles données) ainsi que la callback.

Si vous êtes comme moi et que vous utilisez angular.js un peu partout, vous savez comment il peut s'avérer complexe de s'intégrer dans son dual binding, mais la méthode $scope.$apply est là pour ça!

Voici donc le résultat final :


Et voilà, c'est pas bien compliqué de faire du temps réel :)

Petit précision, EventSource n'est pas supporté par IE, mais il existe un contournement : github.com/Yaffle/EventSource

mercredi 4 juin 2014

Server Sent Events réactifs avec SimpleWeb4j

Nous avons vu hier un exemple simple de Server Sent Events avec SimpleWeb4j, passons maintenant à plus complexe, un exemple dit "réactif", ce n'est pas le flux qui demande la valeur suivante, mais bien un "service" extérieure qui déclenche l'envoi à tous les flux ouverts.

Pour l'exemple, nous allons créer trois générateurs d'événements, avec chacun un délai aléatoire entre les événements.

Nous allons donc tout d'abord créer une classe "Event", cette classe contient un nom, une valeur et l'heure de création. La valeur est créée de manière aléatoire.

Nous allons ensuite créer un générateur, qui est un Runnable infini, et envoi des événements aux handlers SimpleWeb4j.

Un handler SimpleWeb4j est une classe fournie par SimpleWeb4j qui contient une méthode "next" permettant d'envoyer les événements. Nous stockerons ces handlers dans un ConcurrentHashSet pour pouvoir tous les adresser (et pas seulement le dernier flux créé.

Une fois tous ces composants créés, il suffit de déclarer la route, voici donc le résultat final :


J'espère vous avoir montré l'intérêt de SimpleWeb4j sur ce cas beaucoup moins simple que le précédent.

Si le sujet vous intéresse, vous pouvez regarder ma présentation donnée au Breizhcamp sur parleys :

mardi 3 juin 2014

Server Sent Events avec SimpleWeb4j

Je vous ai montré hier comment faire du SSE avec Jetty. Nous allons maintenant voir comment faire avec SimpleWeb4j.

L'exemple avec jetty était une horloge déclenchée toutes les secondes à partir de l'accès à l'url, voyons donc comment coder cela avec SimpleWeb4j : Simple, non?


Dans la vrai vie, on souhaite sans doute pouvoir déclencher simplement l'envoie d'un événement sans être dépendant d'un délai quelconque. Ce sera l'objet de l'article de demain :)

lundi 2 juin 2014

Server Sent Events avec Jetty

Je vais aujourd'hui vous présenter comment faire du Server-Sent-Events (EventSource) avec Jetty.

C'est quoi

Si vous avez déjà lu w3c, passez au chapitre suivant :)

La technologie Server Sent Events (ou EventSource du nom de l'API javascripts) est une technologie permettant de faire du push du serveur vers le client en gardant une connexion ouverte.

Un des gros avantages selon moi de cette technologie est sa simplicité, c'est du texte sur HTTP. Chaque événement est préfixé de "data: ", et on met deux retours à la ligne pour séparer les événements (je simplifie un peu).


Comment je fait coté serveur avec Jetty

Le plus simple est encore de vous montrer le code :)


Demain, je vous montrerai que c'est quand même beaucoup plus simple d'utiliser SimpleWeb4j pour le faire :)

vendredi 30 mai 2014

Services REST avec SimpleWeb4J

Cet article est le deuxième article de la série sur SimpleWeb4j

Dans le première article on a vu comment démarrer SimpleWeb4j en une ligne de code, dans l'article d'aujourd'hui, nous allors voir comment exposer des services REST en json.

Premiers cas : exposer une String "Hello World"

J'espère que le code est suffisamment simple pour ne pas avoir besoin d'explication.

On peux voir qu le résultat est entouré de guillemets, ceci est du au fait que SimpleWeb4j transforme la chaîne de caractère en json.


Deuxième cas : utilisation d'une variable de route

Cet exemple mérite peut-être un peu plus d'explications. SimpleWeb4j permet d'ajouter des paramètres à la route, ces paramètres sont préfixés de ':'. Pour les récupérer on utilise le paramètre RouteParameters qui est le deuxième argument de notre lambda. Le premier argument quand à lui contient l'objet envoyé dans le request body de la requête, nous ne l'utilisons donc pas.


Troisième cas : objet complexe

Nous avons vu que renvoyer une chaîne de caractère était plutôt simple, voyons maintenant comment renvoyer un objet plus complexe.

On peut donc voir que renvoyer un objet n'est pas plus compliqué, SimpleWeb4j s'occupe de transformer celui-ci en json



J'espère vous avoir donner envie de regarder SimpleWeb4j de plus près, si quelque chose vous manque, n'hésitez pas à le dire ou à faire une pull request sur github.

jeudi 29 mai 2014

ConcurrentHashMap et LongAdder

Le sujet du jour est de réaliser un petit filtre de Servlet pour stocker le nombre d'appels pour chaque url.

Pour réaliser cela, il suffit de lire la javadoc de ConcurrentHashMap et plus particulièrement :
A ConcurrentHashMap can be used as scalable frequency map (a form of histogram or multiset) by using LongAdder values and initializing via computeIfAbsent. For example, to add a count to a ConcurrentHashMap<String,LongAdder> freqs, you can use freqs.computeIfAbsent(k -> new LongAdder()).increment();

L'implémentation est donc très simple :

L'affichage n'est pas plus compliqué :

On a donc une gestion de stats thread safe et performante en une ligne de code :)

mercredi 28 mai 2014

SimpleWeb4J - quick start

Ceux qui me suivent connaissent sans doute déjà SimpleWeb4j. Il s'agit d'encore un framework web donc le but est de pouvoir faire du web en java de manière très simple.

Je n'ai jamais écrit d'article sur SimpleWeb4j, je vais donc écrire une série d'articles sur ce sujet afin de vous montrer la simplicité de ce framework.

Je vais commencer par le classique Quick Start, ou comment démarrer un serveur Web capable de servir des ressources statiques.

Dépendance maven

Ressources statiques

Mettez vos ressources statiques au sein d'un package "public" dans votre classpath.

Classe main

Il vous suffit ensuite de démarrer le serveur :

Et voilà, vous avez un serveur prêt sur http://localhost:9999, pas besoin de déclaration xml ou autre complexité, un simple appel à start suffit.

mardi 27 mai 2014

Scheduler en Java

Si je vous demande comment déclencher une tache récurrente en Java, je suis sûr que certains d'entre vous répondront Quartz...

Ceux qui répondent ça ne connaissent sans doute pas les ExecutorService de Java, et plus particulièrement l'interface ScheduledExecutorService (apparue en Java 1.5...).

Voici donc un petit exemple permettant d'afficher l'heure courante toute les secondes :

Ne vous habituez pas à un article par jour, ça ne va pas durer :)

lundi 26 mai 2014

Un cache en java

Après bientôt un an sans écrire d'article, je vais essayer de me remettre à écrire des trucs... Je ne garanti pas que ce soit intéressant :)

Le premiers de cette renaissance sera sur les caches simples en Java.

Je parle ici de cache non révocable (j'en ai eu besoin très récemment). Voici la classe permettant de faire ceci :

Vous l'aurez compris, cet article cherche a vous présenter la méthode ConcurrentHashMap.computeIfAbsent, cette méthode est apparue en Java 8.

Cette dernière permet donc de remplir notre Map si la clé est absente, et ce de manière Thread safe!

J'espère pouvoir publier le prochain article dans moins d'un an, à bientôt donc :)