From d5ca5d66f77208594068e8df1ed44c75413e14e4 Mon Sep 17 00:00:00 2001 From: m-gues Date: Sat, 16 Jan 2021 01:43:59 +0100 Subject: [PATCH] Serveur presence fonctionnel (sans la liste des utilisateurs affichee --- POO/src/communication/CommunicationUDP.java | 6 +- POO/src/connexion/ControleurConnexion.java | 10 +- POO/src/messages/Message.java | 12 +- POO/src/messages/MessageSysteme.java | 4 +- POO/src/messages/MessageTexte.java | 2 + .../src/communication/CommunicationUDP.java | 7 +- POO_Server/src/communication/UDPServer.java | 3 +- POO_Server/src/main/ServletPresence.java | 176 ++++++++++++++++-- POO_Server/src/main/Utilisateur.java | 4 + 9 files changed, 195 insertions(+), 29 deletions(-) diff --git a/POO/src/communication/CommunicationUDP.java b/POO/src/communication/CommunicationUDP.java index 406b155..2028e7d 100644 --- a/POO/src/communication/CommunicationUDP.java +++ b/POO/src/communication/CommunicationUDP.java @@ -106,7 +106,7 @@ public class CommunicationUDP extends Thread { protected synchronized void removeUser(String idClient, String pseudoClient,InetAddress ipClient, int port) { - int index = getIndexFromID(idClient); + int index = getIndexFromIP(ipClient); if( index != -1) { users.remove(index); } @@ -124,7 +124,7 @@ public class CommunicationUDP extends Thread { public void sendMessageConnecte() throws UnknownHostException, IOException { for(int port : this.portOthers) { try { - this.client.sendMessageUDP_local(new MessageSysteme(Message.TypeMessage.JE_SUIS_CONNECTE, Utilisateur.getSelf().getId()), port, InetAddress.getLocalHost()); + this.client.sendMessageUDP_local(new MessageSysteme(Message.TypeMessage.JE_SUIS_CONNECTE), port, InetAddress.getLocalHost()); } catch (MauvaisTypeMessageException e) {/*Si ça marche pas essayer là*/} } } @@ -175,7 +175,7 @@ public class CommunicationUDP extends Thread { public void sendMessageDelete() throws UnknownHostException, IOException { for(int port : this.portOthers) { try { - this.client.sendMessageUDP_local(new MessageSysteme(Message.TypeMessage.JE_SUIS_DECONNECTE, Utilisateur.getSelf().getId()), port, InetAddress.getLocalHost()); + this.client.sendMessageUDP_local(new MessageSysteme(Message.TypeMessage.JE_SUIS_DECONNECTE), port, InetAddress.getLocalHost()); } catch (MauvaisTypeMessageException e) {} } } diff --git a/POO/src/connexion/ControleurConnexion.java b/POO/src/connexion/ControleurConnexion.java index 949d129..030673e 100644 --- a/POO/src/connexion/ControleurConnexion.java +++ b/POO/src/connexion/ControleurConnexion.java @@ -30,19 +30,19 @@ public class ControleurConnexion implements ActionListener, Observer{ try { switch(numtest) { case 0 : - this.comUDP = new CommunicationUDP(2208, 2209, new int[] {2309, 2409}); + this.comUDP = new CommunicationUDP(2208, 2209, new int[] {2309, 2409, 3334}); this.portTCP = 7010; break; case 1 : - this.comUDP = new CommunicationUDP(2308, 2309, new int[] {2209, 2409}); + this.comUDP = new CommunicationUDP(2308, 2309, new int[] {2209, 2409, 3334}); this.portTCP = 7020; break; case 2 : - this.comUDP = new CommunicationUDP(2408, 2409, new int[] {2209, 2309}); + this.comUDP = new CommunicationUDP(2408, 2409, new int[] {2209, 2309, 3334}); this.portTCP = 7030; break; default : - this.comUDP = new CommunicationUDP(2408, 2409, new int[] {2209, 2309}); + this.comUDP = new CommunicationUDP(2408, 2409, new int[] {2209, 2309, 3334}); this.portTCP = 7040; } } catch (IOException e) { @@ -58,7 +58,7 @@ public class ControleurConnexion implements ActionListener, Observer{ id=vue.getValeurTextField(); //Recherche dans la liste des utilisateurs enregistres, report sur inputOK - inputOK = (id.contentEquals("idvalide")||id.contentEquals("idv2")); + inputOK = (id.contentEquals("idvalide")||id.contentEquals("idv2")||id.contentEquals("idv2")); if (inputOK) { this.etat=Etat.ID_OK; diff --git a/POO/src/messages/Message.java b/POO/src/messages/Message.java index ac9c1a5..6036b00 100644 --- a/POO/src/messages/Message.java +++ b/POO/src/messages/Message.java @@ -1,13 +1,17 @@ package messages; import java.io.Serializable; +import java.lang.instrument.Instrumentation; import java.util.Arrays; +import messages.Message.TypeMessage; + public abstract class Message implements Serializable { public enum TypeMessage {JE_SUIS_CONNECTE, JE_SUIS_DECONNECTE, INFO_PSEUDO, TEXTE, IMAGE, FICHIER, MESSAGE_NUL} protected TypeMessage type; private static final long serialVersionUID = 1L; + private static Instrumentation inst; public TypeMessage getTypeMessage() { return this.type; @@ -24,10 +28,10 @@ public abstract class Message implements Serializable { String[] parts = messageString.split("###"); switch (parts[0]) { case "JE_SUIS_CONNECTE" : - return new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE, parts[2]); + return new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE); case "JE_SUIS_DECONNECTE" : - return new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE, parts[2]); + return new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE); case "INFO_PSEUDO" : return new MessageSysteme(TypeMessage.INFO_PSEUDO, parts[1], parts[2], Integer.parseInt(parts[3]) ); @@ -47,8 +51,8 @@ public abstract class Message implements Serializable { //tests ici public static void main(String[] args) throws MauvaisTypeMessageException { - Message m1 = new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE, "sahiu"); - Message m2 = new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE, "putbezfjk"); + Message m1 = new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE); + Message m2 = new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE); Message m3 = new MessageSysteme(TypeMessage.INFO_PSEUDO, "pseudo156434518", "id236", 1500); Message m4 = new MessageTexte(TypeMessage.TEXTE, "blablabla"); Message m5 = new MessageFichier(TypeMessage.FICHIER, "truc", ".pdf"); diff --git a/POO/src/messages/MessageSysteme.java b/POO/src/messages/MessageSysteme.java index 06d3e07..0ff111d 100644 --- a/POO/src/messages/MessageSysteme.java +++ b/POO/src/messages/MessageSysteme.java @@ -7,11 +7,11 @@ public class MessageSysteme extends Message { private String id; private int port; - public MessageSysteme(TypeMessage type, String id) throws MauvaisTypeMessageException{ + public MessageSysteme(TypeMessage type) throws MauvaisTypeMessageException{ if ((type==TypeMessage.JE_SUIS_CONNECTE)||(type==TypeMessage.JE_SUIS_DECONNECTE)||(type==TypeMessage.MESSAGE_NUL)) { this.type=type; this.pseudo=""; - this.id=id; + this.id=""; this.port = -1; } else throw new MauvaisTypeMessageException(); diff --git a/POO/src/messages/MessageTexte.java b/POO/src/messages/MessageTexte.java index 79d1b8c..e5d354d 100644 --- a/POO/src/messages/MessageTexte.java +++ b/POO/src/messages/MessageTexte.java @@ -1,5 +1,7 @@ package messages; +import messages.Message.TypeMessage; + public class MessageTexte extends Message { diff --git a/POO_Server/src/communication/CommunicationUDP.java b/POO_Server/src/communication/CommunicationUDP.java index 51221c7..99cacc6 100644 --- a/POO_Server/src/communication/CommunicationUDP.java +++ b/POO_Server/src/communication/CommunicationUDP.java @@ -42,6 +42,10 @@ public class CommunicationUDP extends Thread { this.observer=obs; } + public Observer getObserver () { + return this.observer; + } + protected boolean containsUserFromID(String id) { for(Utilisateur u : users) { if(u.getId().equals(id) ) { @@ -51,6 +55,7 @@ public class CommunicationUDP extends Thread { return false; } + public boolean containsUserFromPseudo(String pseudo) { for(Utilisateur u : users) { if(u.getPseudo().equals(pseudo) ) { @@ -127,7 +132,7 @@ public class CommunicationUDP extends Thread { users.remove(index); } try { - Message message = new MessageSysteme(Message.TypeMessage.JE_SUIS_DECONNECTE, idClient, pseudoClient, port); + Message message = new MessageSysteme(Message.TypeMessage.JE_SUIS_DECONNECTE, idClient); observer.update(this, message); } catch (MauvaisTypeMessageException e) { e.printStackTrace(); diff --git a/POO_Server/src/communication/UDPServer.java b/POO_Server/src/communication/UDPServer.java index 7db6a3d..e97ff5c 100644 --- a/POO_Server/src/communication/UDPServer.java +++ b/POO_Server/src/communication/UDPServer.java @@ -34,7 +34,7 @@ public class UDPServer extends Thread { this.sockUDP.receive(inPacket); String msgString = new String(inPacket.getData(), 0, inPacket.getLength()); Message msg = Message.stringToMessage(msgString); - + switch(msg.getTypeMessage()) { case JE_SUIS_CONNECTE : @@ -44,6 +44,7 @@ public class UDPServer extends Thread { int portServer = portClient+1; this.commUDP.sendMessageInfoPseudo(portServer); + this.commUDP.getObserver().update(this, portServer); } diff --git a/POO_Server/src/main/ServletPresence.java b/POO_Server/src/main/ServletPresence.java index a541023..700efd8 100644 --- a/POO_Server/src/main/ServletPresence.java +++ b/POO_Server/src/main/ServletPresence.java @@ -1,7 +1,9 @@ package main; import java.io.IOException; +import java.io.PrintWriter; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import javax.servlet.ServletException; @@ -19,8 +21,9 @@ import messages.Message.TypeMessage; */ @WebServlet("/ServletPresence") - -//Penser a modifier comUDP et comTCP pour un serveur !!! (ie pseudo predefini, n'accepte pas les connexions tcp etc) +//Faire un publish (get) séparé en utilisant les cookies pour stocker les modifications : pose problème au niveau de la synchro des pseudos (à dire rapport) +// BUG 1 : problème des conflits de pseudo +//Transmission de la liste des locaux direct du serveur aux externes ? à voir (direct dans le doPost du coup) public class ServletPresence extends HttpServlet implements Observer { private static final long serialVersionUID = 1L; @@ -30,12 +33,18 @@ public class ServletPresence extends HttpServlet implements Observer { public ServletPresence() { //A changer en passant aux IP try { - comUDP = new CommunicationUDP(3333, 3334, new int[0]); + comUDP = new CommunicationUDP(3333, 3334, new int[] {2209, 2309, 2409, 3334}); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } comUDP.setObserver(this); + remoteUsers = new ArrayList(); + try { + Utilisateur.setSelf("serv_p", "Serveur de presence", "localhost", 3334); + } catch (UnknownHostException e) { + e.printStackTrace(); + } } private int getIndexByID(String id) { @@ -47,6 +56,16 @@ public class ServletPresence extends HttpServlet implements Observer { return -1; } + private boolean remoteContainsUserFromPseudo(String pseudo) { + for(Utilisateur u : remoteUsers) { + if(u.getPseudo().equals(pseudo) ) { + return true; + } + } + return false; + } + + //Informe de la modification de la liste tous les utilisateurs internes et externes private void snotify(MessageSysteme message, Utilisateur user) { if (remoteUsers.contains(user)) { @@ -67,36 +86,167 @@ public class ServletPresence extends HttpServlet implements Observer { } // susbribe/unsubscribe : Permet a un utilisateur externe de s'ajouter/s'enlever à la liste des utilisateurs externes : au tout début de l'application - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - Utilisateur user = new Utilisateur(id, pseudo, ip, port); - remoteUsers.add(user); + //Note : le serveur agit comme un proxy pour le TCP et remplace le port de l'utilisateur par le sien + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String id = request.getParameter("id"); + String pseudo = request.getParameter("pseudo"); + int port = Integer.parseInt(request.getParameter("port")); + InetAddress ip = InetAddress.getByName(request.getRemoteAddr()); + + //Si le pseudo est déjà pris : génère du html pour en informer l'utilisateur + if (comUDP.containsUserFromPseudo(pseudo)||remoteContainsUserFromPseudo(pseudo)) { + response.setContentType( "text/html" ); + PrintWriter out = response.getWriter(); + out.println( "" ); + out.println( ""); + out.println( "Erreur pseudo déjà utilisé" ); + out.println( "" ); + out.println( "" ); + out.println( "

Erreur : Ce pseudo est déjà utilisé

" ); + out.println( "

Veuillez choisir un autre pseudo

" ); + out.println( "" ); + out.println( "" ); + out.close(); + } + + //Sinon + else { + Utilisateur user = new Utilisateur(id, pseudo, ip, port); + remoteUsers.add(user); + try { + snotify(new MessageSysteme(Message.TypeMessage.INFO_PSEUDO, pseudo, id, 3334), user); + } catch (MauvaisTypeMessageException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ + String id = request.getParameter("id"); int index = getIndexByID(id); Utilisateur user = remoteUsers.get(index); remoteUsers.remove(index); + try { + snotify(new MessageSysteme(Message.TypeMessage.JE_SUIS_DECONNECTE, id), user); + } catch (MauvaisTypeMessageException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } //Permet de dire si on a changé de pseudo (pour les utilisateurs externes) protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ + String id = request.getParameter("id"); + String pseudo = request.getParameter("pseudo"); int index = getIndexByID(id); - Utilisateur user = remoteUsers.get(index); - user.setPseudo(pseudo); + + //Si le pseudo est déjà pris : génère du html pour en informer l'utilisateur + if (comUDP.containsUserFromPseudo(pseudo)||remoteContainsUserFromPseudo(pseudo)) { + response.setContentType( "text/html" ); + PrintWriter out = response.getWriter(); + out.println( "" ); + out.println( ""); + out.println( "Erreur pseudo déjà utilisé" ); + out.println( "" ); + out.println( "" ); + out.println( "

Erreur : Ce pseudo est déjà utilisé

" ); + out.println( "

Veuillez choisir un autre pseudo

" ); + out.println( "" ); + out.println( "" ); + out.close(); + } + + else { + Utilisateur user = remoteUsers.get(index); + user.setPseudo(pseudo); + try { + snotify(new MessageSysteme(Message.TypeMessage.INFO_PSEUDO, pseudo, id, 3334), user); + } catch (MauvaisTypeMessageException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } - //Informe de la modification de la liste tous les utilisateurs internes et externes protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ - snotify(message, comUDP.getUserFromID(message.getId())); + + try { + String type= request.getParameter("type"); + + switch(type) { + case "POST" : + doPost(request, response); + break; + + case "DELETE" : + doDelete(request, response); + break; + + case "PUT" : + doPut(request, response); + break; + + //génère une jolie page + default : + response.setContentType( "text/html" ); + PrintWriter out = response.getWriter(); + out.println( "" ); + out.println( ""); + out.println( "Erreur requête invalide" ); + out.println( "" ); + out.println( "" ); + out.println( "

Erreur : nous n'avons pas compris votre requête

" ); + out.println( "

Veuillez vérifier votre syntaxe et réessayer

" ); + out.println( "" ); + out.println( "" ); + out.close(); + } + } + //Si pas d'argument type : page d'accueil + catch (java.lang.NullPointerException e) { + response.setContentType( "text/html" ); + PrintWriter out = response.getWriter(); + out.println( "" ); + out.println( ""); + out.println( "Serveur de présence - Accueil" ); + out.println( "" ); + out.println( "" ); + out.println( "

Bienvenue sur le service de connexion à distance

" ); + out.println( "

Vous pouvez taper votre requête dans la barre de navigation

" ); + out.println( "

Requêtes (à ajouter derrière l'URL) :

" ); + out.println( "

Se connecter : ?type=POST&id=[votre id]&pseudo=[pseudo voulu]&port=[port utilisé]

" ); + out.println( "

Se déconnecter : ?type=DELETE&id=[votre id]

" ); + out.println( "

Changer de pseudo : ?type=PUT&id=[votre id]&pseudo=[pseudo voulu]

" ); + out.println( "" ); + out.println( "" ); + out.close(); + + } } + @Override //Note : on part du principe que pour les communications TCP et autres, le serveur agira comme un proxy et donc que les //utilisateurs externes n'ont pas besoin de connaitre les ip internes des machines - //Pourquoi j'ai fait ça ?????? Je change si je me souviens + public void update(Object o, Object arg) { - /*MessageSysteme message = (MessageSysteme) arg; - snotify(message, comUDP.getUserFromID(message.getId()));*/ + // pour transmettre aux utilisateurs externes les modifications internes + if (arg instanceof MessageSysteme) { + MessageSysteme message = (MessageSysteme) arg; + snotify(message, comUDP.getUserFromID(message.getId())); + } + //pour transmettre la liste des utilisateurs externes aux nouveaux arrivants internes + if (arg instanceof Integer) { + int port = (int)arg; + for (Utilisateur u : remoteUsers) { + try { + comUDP.sendMessage(new MessageSysteme(Message.TypeMessage.INFO_PSEUDO, u.getPseudo(), u.getId(), u.getPort()), port); + } catch (MauvaisTypeMessageException e) { + e.printStackTrace(); + } + } + } } } diff --git a/POO_Server/src/main/Utilisateur.java b/POO_Server/src/main/Utilisateur.java index 0546d93..70c6348 100644 --- a/POO_Server/src/main/Utilisateur.java +++ b/POO_Server/src/main/Utilisateur.java @@ -59,4 +59,8 @@ public class Utilisateur implements Serializable{ public static void resetSelf() { Utilisateur.self = null; } + + public String toString(){ + return id + "###" + pseudo; + } }