# Squelette du TP ## Rapport ### Binôme : Thibaut ROCHAS, Tuan Minh VU ### Git : https://gitlab2.istic.univ-rennes1.fr/tuvu/ipd-tp-4 ### Introduction On a utilisé CloudAMQP, qui semblait être la solution la plus meilleur solution pour commencer le TP rapidement. Les exemples ont tous été testés, avec notre serveur RabitMQ. Avec l’aide des exemples et du cours, on a pu faire la partie Date sans grande difficulté. Ensuite, le chat n’était pas très compliqué, on a fait le bonus espion. ### Déroulement du TP #### Exemples Pour les exemples il suffisait simplement de remplacer "localhost" dans le setHost du ConnectionFactory par l’URL de notre serveur RabbitMQ.

Le premier exemple envoie juste un seul message "Hello World", et on enregistre dans le receveur une action à effectuer à chaque message, ici il affiche simplement le message.

Sur le 2ème exemple, l’envoyeur NewTask prend ces arguments, les concatène en un message qu’il envoie au worker, qui va effectuer une action à chaque message reçu : il affiche le message puis attend 1 seconde pour chaque point dans le message reçu, et affiche "done" quand il a fini.

L’exemple 3 prend encore des arguments, il envoie à tous les Receveurs car le type d’échange est "fanout", ici le receveur affiche simplement le message.

Dans l’exemple 4, on utilise le type d’échange "direct", avec des topics, il faut donc aussi fournir le topic en argument en plus du message pour l’envoyeur, et le receveur on lui fournit les topics qu’il doit s’abonner.

L’exemple 5 fait la même chose que le 4, mais avec un type d’échange "topic", il y a donc une hiérarchie dans les topics.
Le dernier exemple est une communication RPC, le client envoie un message et le serveur répond en fonction de ce message.
#### Date À partir de l'exemple 3, on envoie simplement la date, avec le même échange de type fanout. Pour générer la date, on fait simplement une fonction getDate() qui retourne (new Date()).toString();
Le reste est identique à tuto3.java.
Chaque client reçoit le message du serveur correctement.

Pour tester on a executé un EnvoyerDate, et 2 RecevoirDate :
EnvoyerDate RecevoirDate (1) RecevoirDate (2)
[x] Sent 'Sat Apr 26 10:06:24 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:25 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:26 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:27 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:28 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:29 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:30 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:31 CEST 2025'
[x] Sent 'Sat Apr 26 10:06:32 CEST 2025'
[x] Received 'Sat Apr 26 10:06:24 CEST 2025'
[x] Received 'Sat Apr 26 10:06:25 CEST 2025'
[x] Received 'Sat Apr 26 10:06:26 CEST 2025'
[x] Received 'Sat Apr 26 10:06:27 CEST 2025'
[x] Received 'Sat Apr 26 10:06:28 CEST 2025'
[x] Received 'Sat Apr 26 10:06:29 CEST 2025'
[x] Received 'Sat Apr 26 10:06:30 CEST 2025'
[x] Received 'Sat Apr 26 10:06:31 CEST 2025'
[x] Received 'Sat Apr 26 10:06:32 CEST 2025'
[x] Received 'Sat Apr 26 10:06:24 CEST 2025'
[x] Received 'Sat Apr 26 10:06:25 CEST 2025'
[x] Received 'Sat Apr 26 10:06:26 CEST 2025'
[x] Received 'Sat Apr 26 10:06:27 CEST 2025'
[x] Received 'Sat Apr 26 10:06:28 CEST 2025'
[x] Received 'Sat Apr 26 10:06:29 CEST 2025'
[x] Received 'Sat Apr 26 10:06:30 CEST 2025'
[x] Received 'Sat Apr 26 10:06:31 CEST 2025'
[x] Received 'Sat Apr 26 10:06:32 CEST 2025'
##### Date Partage d’une même file Pour la version de partages d'un même fil, c'est la même chose que la version précédente mais cette fois si un seul client reçoit le message, tous les clients ne reçoivent donc pas tous les messages, chaque message est unique.

Pour tester on a executé un EnvoyerDate, et 2 RecevoirDate pour vérifier que chaque message n'est reçu que par un seul client :
EnvoyerDate RecevoirDate (1) RecevoirDate (2)
[x] Sent 'Sat Apr 26 10:21:46 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:47 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:48 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:49 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:50 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:51 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:52 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:53 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:54 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:55 CEST 2025'
[x] Sent 'Sat Apr 26 10:21:56 CEST 2025'
[x] Received 'Sat Apr 26 10:21:46 CEST 2025'
[x] Received 'Sat Apr 26 10:21:48 CEST 2025'
[x] Received 'Sat Apr 26 10:21:50 CEST 2025'
[x] Received 'Sat Apr 26 10:21:52 CEST 2025'
[x] Received 'Sat Apr 26 10:21:54 CEST 2025'
[x] Received 'Sat Apr 26 10:21:56 CEST 2025'
[x] Received 'Sat Apr 26 10:21:47 CEST 2025'
[x] Received 'Sat Apr 26 10:21:49 CEST 2025'
[x] Received 'Sat Apr 26 10:21:51 CEST 2025'
[x] Received 'Sat Apr 26 10:21:53 CEST 2025'
[x] Received 'Sat Apr 26 10:21:55 CEST 2025'
On peut donc bien voir que les messages sont partagés entre les clients ##### Date Routage simple Dans cette version, on peut choisir une clef de routage, dans dateRoot on a donc la clef "local" et la clef "GMT" dans EnvoyerDate on envoie donc avec ses clefs respectivement, la date locale (la même que précédement), et la date GMT (la même chose mais juste a remplaçant .toString() à .toGMTString() ). On a maintenant deux receveurs, RecvoirDate, qui s'abonne à la clef "local" et RecevoirGMT qui s'abonne à la clef "GMT".

On lance chaque Class :
EnvoyerDate RecevoirDate RecevoirDateGMT
[x] Sent 'Sat Apr 26 10:46:56 CEST 2025'
[x] Sent '26 Apr 2025 08:46:56 GMT'
[x] Sent 'Sat Apr 26 10:46:57 CEST 2025'
[x] Sent '26 Apr 2025 08:46:57 GMT'
[x] Sent 'Sat Apr 26 10:46:58 CEST 2025'
[x] Sent '26 Apr 2025 08:46:58 GMT'
[x] Sent 'Sat Apr 26 10:46:59 CEST 2025'
[x] Sent '26 Apr 2025 08:46:59 GMT'
[x] Sent 'Sat Apr 26 10:47:00 CEST 2025'
[x] Sent '26 Apr 2025 08:47:00 GMT'
[x] Sent 'Sat Apr 26 10:47:01 CEST 2025'
[x] Sent '26 Apr 2025 08:47:01 GMT'
[x] Sent 'Sat Apr 26 10:47:03 CEST 2025' [x] Sent '26 Apr 2025 08:47:03 GMT'
[x] Received 'Sat Apr 26 10:46:56 CEST 2025'
[x] Received 'Sat Apr 26 10:46:57 CEST 2025'
[x] Received 'Sat Apr 26 10:46:58 CEST 2025'
[x] Received 'Sat Apr 26 10:46:59 CEST 2025'
[x] Received 'Sat Apr 26 10:47:00 CEST 2025'
[x] Received 'Sat Apr 26 10:47:01 CEST 2025'
[x] Received 'Sat Apr 26 10:47:03 CEST 2025'
[x] Received '26 Apr 2025 08:46:56 GMT'
[x] Received '26 Apr 2025 08:46:57 GMT'
[x] Received '26 Apr 2025 08:46:58 GMT'
[x] Received '26 Apr 2025 08:46:59 GMT'
[x] Received '26 Apr 2025 08:47:00 GMT'
[x] Received '26 Apr 2025 08:47:01 GMT'
[x] Received '26 Apr 2025 08:47:03 GMT'
La Class Recevoir reçoit bien uniquement les dates locales et RecevoirDateGMT les dates GMT ##### Date Routage par Topic On utilise maintenant des topics, tout comme le Routage précédent on peut s'abonner à des clef, mais dans ce cas là, ce sont des chemain, par exemple au lieu d'uniquement "local" et "GMT" c'est "date.local" et "date.GMT", cette fois si les deux topic on un point commu dans leur chemain, il et donc possible de s'abonner uniquement à "local", uniquement à "GMT" ou à toutes les dates avec "date.#".

Encore une fois on lance chaque Class :
EnvoyerDate RecevoirDate RecevoirDateGMT RecevoirToutesDates
[x] Sent 'Sat Apr 26 10:54:08 CEST 2025'
[x] Sent '26 Apr 2025 08:54:08 GMT'
[x] Sent 'Sat Apr 26 10:54:09 CEST 2025'
[x] Sent '26 Apr 2025 08:54:09 GMT'
[x] Sent 'Sat Apr 26 10:54:10 CEST 2025'
[x] Sent '26 Apr 2025 08:54:10 GMT'
[x] Sent 'Sat Apr 26 10:54:11 CEST 2025'
[x] Sent '26 Apr 2025 08:54:11 GMT'
[x] Sent 'Sat Apr 26 10:54:12 CEST 2025'
[x] Sent '26 Apr 2025 08:54:12 GMT'
[x] Sent 'Sat Apr 26 10:54:13 CEST 2025'
[x] Sent '26 Apr 2025 08:54:13 GMT'
[x] Sent 'Sat Apr 26 10:54:14 CEST 2025'
[x] Sent '26 Apr 2025 08:54:14 GMT'
[x] Received 'Sat Apr 26 10:54:08 CEST 2025'
[x] Received 'Sat Apr 26 10:54:09 CEST 2025'
[x] Received 'Sat Apr 26 10:54:10 CEST 2025'
[x] Received 'Sat Apr 26 10:54:11 CEST 2025'
[x] Received 'Sat Apr 26 10:54:12 CEST 2025'
[x] Received 'Sat Apr 26 10:54:13 CEST 2025'
[x] Received 'Sat Apr 26 10:54:14 CEST 2025'
[x] Received '26 Apr 2025 08:54:08 GMT'
[x] Received '26 Apr 2025 08:54:09 GMT'
[x] Received '26 Apr 2025 08:54:10 GMT'
[x] Received '26 Apr 2025 08:54:11 GMT'
[x] Received '26 Apr 2025 08:54:12 GMT'
[x] Received '26 Apr 2025 08:54:13 GMT'
[x] Received '26 Apr 2025 08:54:14 GMT'
[x] Received 'Sat Apr 26 10:54:08 CEST 2025'
[x] Received '26 Apr 2025 08:54:08 GMT'
[x] Received 'Sat Apr 26 10:54:09 CEST 2025'
[x] Received '26 Apr 2025 08:54:09 GMT'
[x] Received 'Sat Apr 26 10:54:10 CEST 2025'
[x] Received '26 Apr 2025 08:54:10 GMT'
[x] Received 'Sat Apr 26 10:54:11 CEST 2025'
[x] Received '26 Apr 2025 08:54:11 GMT'
[x] Received 'Sat Apr 26 10:54:12 CEST 2025'
[x] Received '26 Apr 2025 08:54:12 GMT'
[x] Received 'Sat Apr 26 10:54:13 CEST 2025'
[x] Received '26 Apr 2025 08:54:13 GMT'
[x] Received 'Sat Apr 26 10:54:14 CEST 2025'
[x] Received '26 Apr 2025 08:54:14 GMT'
RecevoirTouesDates reçoit toutes les dates comme convenu, RecevoirDate uniquement les dates locales et RecevoirDateGMT les dates GMT. #### Chat Ce chat utilise des topics, on pourra donc y avoir des canaux, où les clients pourront s'abonner.

En s'abonnant à un canal, le client reçoit donc uniquement les messages liés à ce canal, et envoie des messages dans ce canal. Le client commence par s'abonner au canal choisi (en 1er argument, ou "#" (tous les canaux) si pas d'argument et dans 2ème argument on peut aussi mettre un nom d'utilisateur, String random sinon), puis on entre dans la boucle pour envoyer les messages, on utilise simplement un scanner.

Pour que les utilisateurs puissent s'identifier entre eux, on intègre le nom d'utilisateur dans le header des Properties de chaque message, avec la clef "sender". Le receveur doit également connaître de quel canal vient le message (pas forcément le même que lui-même dans le cas, par exemple, où l'on utilise "#") Envois d'un message : ```java Map headers = new HashMap<>(); headers.put("sender", name); AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().headers(headers).build(); ``` Reception d'un message : ```java Object senderName = (delivery.getProperties().getHeaders().get("sender")); String routing = delivery.getEnvelope().getRoutingKey(); ``` Pour le test, on va faire deux utilisateurs dans le même canal : Alice et Bob, un dans un canal voisin : Charlie, et un dans le canal parent aux deux précédents : David, et enfin l'Espion qui peut voir tous les canaux :
(ordre des messages : Alice "Bonjour" , Bob "Salut" , David "Hello" , Charlie "je suis tout seul ?")
ClientChat main.salon1 Alice ClientChat main.salon1 Bob ClientChat main.salon2 Chalie ClientChat main.# David Espion
[*] Waiting for messages. To exit press CTRL+C
Bonjour
main.salon1#Alice>Bonjour
main.salon1#Bob>Salut
[*] Waiting for messages. To exit press CTRL+C
main.salon1#Alice>Bonjour
Salut
main.salon1#Bob>Salut
[*] Waiting for messages. To exit press CTRL+C
je suis seul ?
main.salon2#Charlie>je suis seul ?
[*] Waiting for messages. To exit press CTRL+C
main.salon1#Alice>Bonjour
main.salon1#Bob>Salut
hello
main.##David>hello
main.salon2#Charlie>je suis seul ?
[*] Waiting for messages. To exit press CTRL+C
main.salon1#Alice>Bonjour
main.salon1#Bob>Salut
main.##David>hello
main.salon2#Charlie>je suis seul ?
L'Espion voit tous les messages comme prévu, David (main.#) peut lire tous les messages de Alice, Bob et Charlie (et les siens). Alice et Bob voient uniquement les messages de main.salon1, et Charlie ne voit aucun autre message que les siens car il est seul dans le main.salon2.