TP Noté 2016 : chatrooms

Dans ce sujet, nous vous demandons de réaliser un client puis un serveur permettant d'avoir des salles de discussions à deux. Le client et le serveur doivent être écrits en utilisant la bibliothèque Java NIO.

Commencez par créer un nouveau projet Java dans votre environnement que vous appellez tpnote-VotreNom. Créez aussi dans cette arborescence du projet un fichier readme.txt dans lequel vous mettrez vos notes. Créez un paquetage chatrooms dans votre project Eclipse.

Le barème est donné à titre d'indication.

En fin de TP :

  1. si ce n'est pas déjà fait, créez un fichier readme.txt dans lequel vous mettez vos notes à destination des correcteurs ;
  2. exportez votre projet Eclipse sous la forme d'une archive :
  3. déposez le fichier sur moodle comme devoir ;
  4. vérifiez avec l'enseignant présent dans la salle que le fichier téléchargé est correct.

1. Présentation du sujet

Objectif : écrire des classes qui permettent de réaliser un client puis un serveur de chatrooms. Une chatroom est identifiée par une chaîne de caractères. Chaque chatroom permet à deux clients d'avoir une conversation privée.

Pour ce faire, chacun des clients met en œuvre le comportement suivant :

2. Partie Client (8pts)

Dans cette partie, vous devez écrire des clients qui interagissent avec le serveur associé au port 3000 sur la machine ssh.tem-tsp.eu.

2.1 Connexion au serveur et choix d'une chatroom (4pts)

Écrivez la classe ChatHandshake se connectant au serveur et réalisant les étapes décrites ci-dessous :

  1. le client se connecte au serveur ssh.tem-tsp.eu sur le port 3000;
  2. il lit la chaîne de caractères qui sert à identifier la chatroom au clavier ;
  3. il crée un objet du type HalfDuplexMsgWorker ;
  4. il envoie un message de type 1 contenant la chaîne de caractères via cet objet ;
  5. il reçoit, via l'objet HalfDuplexMsgWorker, un message de type 2 contenant un objet de type Integer ;
  6. il affiche la valeur obtenue du serveur ;
  7. il ferme le canal utilisé pour cette première étape.

Vous pouvez vérifier en lançant votre client trois fois que vous recevez deux fois un numéro de salle et -1 la troisième fois. En effet, lorsqu'une salle de tchat est complète (avec deux utilisateurs), le serveur retourne -1 dans l'Integer.

2.2 Connexion au point de tchat et tchat (4pts)

Une fois le handshake réussit, il est nécessaire de se connecter au point de tchat puis de tchater :

  1. le client doit donc se connecter au serveur sur le numéro de port qu'il a reçu, à la condition que ce numéro soit différent de -1 ;
  2. il utilise le canal créé via un ChatClient pour tchater avec son partenaire. Cette partie se caractérise par des émissions et des réceptions de messages dans un mode full-duplex ;

Vous pouvez vous inspirer de ChatClientMain.

Écrivez la classe ChatRoomClientMain réalisant l'ensemble des opérations et capable d'échanger des messages.

3. Partie Serveur (12pts)

3.1. Handshake coté serveur (4pts)

Écrivez une classe ChatRoomServerHandShake qui :

  1. est en attente de connexion sur un ServerSocketChannel associé au numéro de port passé dans les arguments du main (3000 dans l'exemple précédent) ;
  2. et, lorsqu'un client se connecte à ce port :
    1. utilise un HalfDuplexMsgWorker pour recevoir un message de type 1. Ce message doit contenir une chaîne de caractères ;
    2. crée un ServerSocketChannel associé à port de numéro unique qui commence à 3100 ;
    3. et retourne ce numéro de port dans un Integer transmis à partir du HalfDuplewMsgWorker dans un message de type 2.

3.2. Serveur d'une chatroom (4pts)

Écrivez une classe ChatRoomServer qui gère une salle de tchat :

  1. ce serveur permet à un ensemble de clients de se connecter à sa salle de tchat (2 clients dans notre exemple)  ;
  2. il utilise des objets de la classe FullDuplexMsgWorker pour gèrer les communications avec chaque client ;
  3. il utilise un Selector pour se mettre en attente des messages en provenances de ses clients ;
  4. lorsqu'un canal devient actif en lecture, le ChatRoomServer reçoit un message (type 3) associé à une chaîne de caractères. Il transmet alors ce message aux autres clients de la salle de tchat ;
  5. lorsqu'un canal devient actif car un client a fermé sa connexion, le serveur sort de sa boucle sans fin et ferme toutes ses connexions.

Chaque ChatRoomServer posséde un état interne lui permettant de savoir si un nouveau client peut se connecter. Cet état interne doit être associé à une méthode de type get qui permet de le consulter.

3.3. Gestion de l'ensemble des chatrooms (4pts)

Cette classe, que vous appelez, ChatRoomServerMain doit :

  1. mettre en œuvre la partie handshake que nous avons décrite à la question 3.1 ;
  2. gérer la création des ChatRoomServer. Pour que chaque serveur de chatroom soit autonome, nous vous recommandons de l'attacher à un thread d'exécution.
  3. ainsi que les démarage des ChatRoomserver ;
  4. et gérer des structures de données pour tenir à jour les informations pertinentes, à savoir :
    1. prochain numéro de port à attribuer au prochain ChatRoomServer ;
    2. association entre les noms des chatrooms et les serveurs.