Pārlūkot izejas kodu

:sparkles: Fin class reseaux client java

Arthur Brandao 6 gadi atpakaļ
vecāks
revīzija
4e0498cd88

+ 46 - 5
Client/rsx/BomberStudentClient.java

@@ -5,8 +5,11 @@
  */
 package rsx;
 
+import java.io.IOException;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.HashMap;
+import org.json.JSONException;
 import org.json.JSONObject;
 import rsx.tcp.TcpClient;
 import rsx.udp.Broadcast;
@@ -37,6 +40,16 @@ public class BomberStudentClient {
      * Class pour le client TCP
      */
     protected TcpClient socket;
+    
+    /**
+     * Class de gestion des requetes serveurs
+     */
+    protected BomberStudentRequest request;
+    
+    /**
+     * Liste des handlers pour gerer les requetes du serveur
+     */
+    protected HashMap<String, BomberStudentHandler> handlers = new HashMap<>();
 
     /* --- Constructeurs --- */
     /**
@@ -62,6 +75,15 @@ public class BomberStudentClient {
     }
 
     /* --- Methodes --- */
+    /**
+     * Ajoute un handler
+     * @param ressource Le nom de la ressource associè au handler
+     * @param handler Le handler
+     */
+    public void addHandler(String ressource, BomberStudentHandler handler){
+        this.handlers.put(ressource, handler);
+    }
+    
     /**
      * Cherche un serveur par broadcast
      * @return Le nombre de serveur trouvé
@@ -83,6 +105,14 @@ public class BomberStudentClient {
             System.err.println("Index invalide");
             return false;
         }
+        //Lancement gestionnaire des requetes serveur
+        try {
+            this.request = new BomberStudentRequest(serv.get(index), this.portTcp + 1, handlers);
+            this.request.start();
+        } catch (IOException ex) {
+            return false;
+        }
+        //Creation socket d'envoi
         this.socket = new TcpClient(serv.get(index), this.portTcp);
         return this.socket.connect();
     }
@@ -126,12 +156,13 @@ public class BomberStudentClient {
      * Attend une reponse du serveur
      * @return La reponse analysée
      */
-    public BomberStudentReponse receive() {
+    public JSONObject receive() {
         String msg = this.socket.receive();
-        if (msg == null) {
-            return new BomberStudentReponse();
-        } else {
-            return new BomberStudentReponse(msg);
+        try {
+            return new JSONObject(msg);
+        } catch(JSONException ex){
+            System.err.println("La reponse n'est pas en JSON : " + ex.getMessage());
+            return null;
         }
     }
 
@@ -140,6 +171,16 @@ public class BomberStudentClient {
      * @return Reussite
      */
     public boolean close() {
+        this.request.interrupt();
+        //Verif que le thread est bien arréte
+        try {
+            Thread.sleep(3000);
+            if(this.request.isAlive()){
+                System.err.println("Imposible de tuer le thread de gestion des requetes");
+            }
+        } catch (InterruptedException ex) {
+            
+        }
         return this.socket.close();
     }
 

+ 13 - 0
Client/rsx/BomberStudentHandler.java

@@ -0,0 +1,13 @@
+package rsx;
+
+import org.json.JSONObject;
+
+/**
+ * Interface des gestionnaires de requete du serveur
+ * @author Arthur Brandao
+ */
+public interface BomberStudentHandler {
+    
+    public boolean handle(JSONObject json);
+    
+}

+ 0 - 95
Client/rsx/BomberStudentReponse.java

@@ -1,95 +0,0 @@
-package rsx;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-
-/**
- * Analyse reponse d'un serveur BomberStudent
- *
- * @author Arthur Brandao
- */
-public class BomberStudentReponse {
-
-    /**
-     * Reponse valide ou non
-     */
-    protected boolean error = true;
-    
-    /**
-     * Code du statut encoyé par le serveur
-     */
-    protected int statut;
-    
-    /**
-     * Message du statut envoyé par le serveur
-     */
-    protected String message;
-    
-    /**
-     * Information en JSON envoyé par le serveur
-     */
-    protected JSONObject reponse = null;
-
-    /* --- Constructeurs --- */
-    /**
-     * Constructeur par defaut en cas de reponse invalide
-     */
-    public BomberStudentReponse() {
-
-    }
-
-    /**
-     * Parse la reponse du serveur
-     * @param reponse La reponse en JSON à parser
-     */
-    public BomberStudentReponse(String reponse) {
-        this.error = false;
-        //Parse reponse
-        try {
-            JSONObject json = new JSONObject(reponse);
-            this.statut = json.getInt("statut");
-            this.message = json.getString("message");
-            if(json.has("param")){
-                this.reponse = json.getJSONObject("param");
-            }
-            this.error = false;
-        } catch(JSONException ex){
-            System.err.println("La reponse n'est pas en JSON : " + ex.getMessage());
-        }
-
-    }
-
-    /* --- Getter/Setter --- */
-    public boolean isError() {
-        return error;
-    }
-
-    public void setError(boolean error) {
-        this.error = error;
-    }
-
-    public int getStatut() {
-        return statut;
-    }
-
-    public void setStatut(int statut) {
-        this.statut = statut;
-    }
-
-    public String getMessage() {
-        return message;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    public JSONObject getReponse() {
-        return reponse;
-    }
-
-    public void setReponse(JSONObject reponse) {
-        this.reponse = reponse;
-    }
-
-}

+ 97 - 0
Client/rsx/BomberStudentRequest.java

@@ -0,0 +1,97 @@
+package rsx;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.json.JSONException;
+import org.json.JSONObject;
+import rsx.tcp.TcpClient;
+
+/**
+ * Analyse les requetes emises par le serveur
+ *
+ * @author Arthur Brandao
+ */
+public class BomberStudentRequest extends Thread {
+
+    /**
+     * Indique si on coupe la boucle
+     */
+    private final AtomicBoolean running = new AtomicBoolean(true);
+
+    /**
+     * Connexion au serveur
+     */
+    protected TcpClient socket;
+
+    /**
+     * Liste des handler à appeler
+     */
+    protected HashMap<String, BomberStudentHandler> handlers;
+
+    /* --- Constructeur --- */
+    public BomberStudentRequest(InetAddress adr, int port, HashMap<String, BomberStudentHandler> handlers) throws IOException {
+        this.handlers = handlers;
+        this.socket = new TcpClient(adr, port);
+        this.socket.timeout(2);
+        if (!this.socket.connect()) {
+            System.err.println("Impossible de créer la socket");
+            throw new IOException("Connexion impossible");
+        }
+    }
+
+    /* --- Surcharge --- */
+    @Override
+    public void interrupt() {
+        this.running.set(false);
+        super.interrupt();
+    }
+
+    @Override
+    public void run() {
+        //Tant qu'actif
+        while (this.running.get()) {
+            //Attente contact serveur
+            String msg = this.socket.receive();
+            //Si rien on continue
+            if (msg == null) {
+                continue;
+            }
+            //Traitement du message
+            String[] requete = msg.split("\n");
+            if (requete.length < 2) {
+                continue;
+            }
+            //Regarde la requete
+            String[] entete = requete[0].split(" ");
+            if (entete.length < 2) {
+                continue;
+            }
+            if (!entete[0].equals("POST")) {
+                continue;
+            }
+            //Regarde si il existe un handler
+            String ressource = entete[1];
+            if (!this.handlers.containsKey(ressource)) {
+                continue;
+            }
+            //Recup json
+            JSONObject json = null;
+            try {
+                json = new JSONObject(requete[1]);
+            } catch (JSONException ex) {
+                System.err.println("La requete n'est pas en JSON : " + ex.getMessage());
+                continue;
+            }
+            //Appel handler
+            BomberStudentHandler handler = this.handlers.get(ressource);
+            if(!handler.handle(json)){
+                System.err.println("Erreur pendant l'execution du handler");
+            }
+        }
+        //Fermeture socket
+        this.socket.close();
+    }
+
+}

+ 55 - 27
Client/rsx/tcp/TcpClient.java

@@ -18,66 +18,91 @@ import java.net.UnknownHostException;
  * @author loquicom
  */
 public class TcpClient {
-    
+
     /**
      * Adresse du serveur
      */
     protected InetAddress adr;
-    
+
     /**
      * Port du serveur
      */
     protected int port;
-    
+
     /**
      * Socket TCP
      */
     protected Socket socket;
-    
+
+    /**
+     * Timeout de la socket (en milisecondes)
+     */
+    protected int timeout = 0;
+
     /**
      * Flux d'entrée
      */
     protected BufferedReader input;
-    
+
     /**
      * Flux de sorti
      */
     protected PrintWriter output;
-    
+
     /* --- Constructeurs --- */
-    
     /**
      * Creation d'un client TCP
+     *
      * @param ip L'ip du serveur
      * @param port Le port du serveur
-     * @throws UnknownHostException 
+     * @throws UnknownHostException
      */
-    public TcpClient(String ip, int port) throws UnknownHostException{
+    public TcpClient(String ip, int port) throws UnknownHostException {
         this.adr = InetAddress.getByName(ip);
         this.port = port;
     }
-    
+
     /**
      * Creation d'un client TCP
+     *
      * @param adr L'adresse du serveur
      * @param port Le port du serveur
      */
-    public TcpClient(InetAddress adr, int port){
+    public TcpClient(InetAddress adr, int port) {
         this.adr = adr;
         this.port = port;
     }
-    
+
     /* --- Methodes --- */
-    
+    /**
+     * Temps avant timeout du receive (qui retournera false)
+     * @param second Le temps en senconde
+     */
+    public void timeout(int second) {
+        this.timeout = second * 1000;
+    }
+
+    /**
+     * Retire un timeout
+     */
+    public void notimeout() {
+        this.timeout = 0;
+    }
+
     /**
      * Connexion au serveur
+     *
      * @return Reussite
      */
-    public boolean connect(){
+    public boolean connect() {
         try {
             this.socket = new Socket(this.adr, this.port);
+            //Si un timeout
+            if (this.timeout > 0) {
+                this.socket.setSoTimeout(this.timeout);
+            }
+            //Ouverture flux
             this.input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
-            //this.output = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream())));
             this.output = new PrintWriter(this.socket.getOutputStream());
         } catch (IOException ex) {
             System.err.println("Impossible de se connecter au serveur : " + ex.getMessage());
@@ -85,36 +110,42 @@ public class TcpClient {
         }
         return true;
     }
-    
+
     /**
      * Envoi message au serveur
+     *
      * @param msg Le message
      * @return Reussite
      */
-    public boolean send(String msg){
+    public boolean send(String msg) {
         output.print(msg);
         output.flush();
         return true;
     }
-    
+
     /**
      * Reception d'un message du serveur
+     *
      * @return Le message ou null en cas d'erreur
      */
-    public String receive(){
+    public String receive() {
         try {
             return input.readLine();
         } catch (IOException ex) {
-            System.err.println("Impossible de lire : " + ex.getMessage());
+            //Si pas l'exception du timeout
+            if (!ex.getMessage().equals("Read timed out")) {
+                System.err.println("Impossible de lire : " + ex.getMessage() + " ");
+            }
             return null;
         }
     }
-    
+
     /**
      * Ferme la connexion au serveur
+     *
      * @return Reussite
      */
-    public boolean close(){
+    public boolean close() {
         try {
             input.close();
             output.close();
@@ -125,9 +156,8 @@ public class TcpClient {
         }
         return true;
     }
-    
-    /* --- Getter/Setter --- */
 
+    /* --- Getter/Setter --- */
     public InetAddress getAdr() {
         return adr;
     }
@@ -143,7 +173,5 @@ public class TcpClient {
     public void setPort(int port) {
         this.port = port;
     }
-    
-    
-    
+
 }

+ 18 - 0
Client/test/ServerHandlerTest.java

@@ -0,0 +1,18 @@
+package test;
+
+import org.json.JSONObject;
+import rsx.BomberStudentHandler;
+
+/**
+ *
+ * @author Arthur Brandao
+ */
+public class ServerHandlerTest implements BomberStudentHandler{
+
+    @Override
+    public boolean handle(JSONObject json) {
+        System.out.println(json.toString(1));
+        return true;
+    }
+    
+}

+ 11 - 5
Client/test/ServerTest.java

@@ -2,8 +2,9 @@ package test;
 
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import org.json.JSONObject;
 import rsx.BomberStudentClient;
-import rsx.BomberStudentReponse;
+import rsx.BomberStudentRequest;
 import rsx.tcp.TcpClient;
 
 /**
@@ -15,7 +16,7 @@ public class ServerTest {
     /**
      * @param args the command line arguments
      */
-    public static void main(String[] args) throws UnknownHostException {
+    public static void main(String[] args) throws InterruptedException {
         
         /*
         Broadcast b = new Broadcast(18426);
@@ -32,15 +33,20 @@ public class ServerTest {
         //*
         BomberStudentClient bsc = new BomberStudentClient();
         int a = bsc.findServer();
-        System.out.println(a);
         if(a == 0){
             System.err.println("Aucun serveur");
             return;
         }
+        bsc.addHandler("test", new ServerHandlerTest());
         bsc.selectServer(0);
         bsc.send("POST", "aze/rty");
-        BomberStudentReponse bsr = bsc.receive();
-        //*/      
+        System.out.println("A");
+        Thread.sleep(15000);
+        System.out.println("B");
+        JSONObject json = bsc.receive();
+        System.out.println(json.toString(1));
+        bsc.close();
+        //*/
     }
     
 }