Compare commits

...

17 commits

Author SHA1 Message Date
82f3cbd91f Rapport POO finito 2021-02-15 17:51:41 +01:00
42f8d92b9d Rajout du manuel d'installation dans README 2021-02-15 17:44:18 +01:00
0c7bcb7b51 ajout des executables
é
2021-02-15 15:05:05 +01:00
a33aeb87ed Merge branch 'master' of https://git.etud.insa-toulouse.fr/gallois/Clavardage
Fichiers supprimer et corrections dans controller.java
+ vidéo démosntration
2021-02-15 14:54:41 +01:00
6917a454e7 vidéo de démonstration 2021-02-15 14:52:13 +01:00
a9fa3e3ef4 Upload files to '' 2021-02-15 11:50:11 +01:00
0ca69de2c3 Getting rid of older files 2021-02-14 13:12:01 +01:00
d8557a852f Getting rid of older files 2021-02-14 13:11:28 +01:00
772c039b51 Final COO Diagrams 2021-02-14 13:05:11 +01:00
LMAGallois
00b3ad3038 Merge branch 'master' of https://git.etud.insa-toulouse.fr/gallois/Clavardage 2021-02-13 13:29:46 +01:00
LMAGallois
94031cc356 websocket 2021-02-13 13:29:22 +01:00
9633bf0f5d Transférer les fichiers vers '' 2021-02-09 20:56:58 +01:00
LMAGallois
72d6f53020 websocket 2021-02-09 20:54:17 +01:00
LMAGallois
fb7c74480c suppression servlet 2021-02-02 16:42:01 +01:00
2d48a2b0d4 historique fix & pollisage du package controller 2021-01-08 21:54:17 +01:00
3ba80fc0a7 historique fix & pollisage du package controller 2021-01-08 21:52:19 +01:00
LMAGallois
31d1638917 centralized server 2021-01-08 18:59:44 +01:00
36 changed files with 686 additions and 205 deletions

View file

@ -1,6 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="C:/Program Files (x86)/MySQL/Connector J 8.0/mysql-connector-java-8.0.22.jar"/>
<classpathentry kind="lib" path="C:/Program Files/tyrus-standalone-client-1.9.jar"/>
<classpathentry kind="lib" path="C:/Program Files/javax.websocket-client-api-1.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View file

@ -1,3 +1,2 @@
/websocket/
/controller/ /controller/
/model/
/view/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -8,6 +8,7 @@ import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.DateFormat; import java.text.DateFormat;
@ -17,6 +18,7 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
//import javax.websocket.DeploymentException;
import model.Chat; import model.Chat;
import model.LocalUser; import model.LocalUser;
@ -24,11 +26,12 @@ import model.Message;
import model.Msg_Text; import model.Msg_Text;
import model.RemoteUser; import model.RemoteUser;
import view.Interface; import view.Interface;
//import websocket.Appel;
public class Controller { public class Controller {
/*** CONSTANTES ***/ /*** CONSTANTES ***/
int NB_SECOND_WAITING_RESPONSE_BROADCAST = 2; final int NB_SECOND_WAITING_RESPONSE_BROADCAST = 1;
// TO REMOVE when we use broadcast // TO REMOVE when we use broadcast
final static int portUDPlistening_remoteUsr1 = 31001; final static int portUDPlistening_remoteUsr1 = 31001;
@ -41,15 +44,15 @@ public class Controller {
/*** ATTRIBUTS ***/ /*** ATTRIBUTS ***/
protected LocalUser myUser; protected LocalUser myUser;
protected Interface view; protected Interface view;
private ListeningThreadUDP udp_connect_thread; private TListeningUDP udp_connect_thread;
private ListeningThreadTCPConnection tcp_connect_thread; private TListeningTCPConnection tcp_connect_thread;
private Historique histoire; private Historique histoire;
protected Chat activeChat; protected Chat activeChat;
/** /**
* Constructor of Controller * Constructor of Controller
* @parametres * @parametres
* @param portUDPsend : int => le numéro de port pour envoyé ces informations lors d'un changements ou d'une nouvelle connexion * @param portUDPsend : int => le numéro de port pour envoyer ces informations lors d'un changements ou d'une nouvelle connexion
* @param portUDPlistening : int => le numéro de port pour recevoir les informations des nouveaux utilisateurs ou les changements * @param portUDPlistening : int => le numéro de port pour recevoir les informations des nouveaux utilisateurs ou les changements
* @param portTCP : int => le numéro de port pour commencer une nouvelle conversation * @param portTCP : int => le numéro de port pour commencer une nouvelle conversation
* @throws IOException * @throws IOException
@ -85,9 +88,9 @@ public class Controller {
} }
// Création des threads d'écoutes // Création des threads d'écoutes
this.udp_connect_thread = new ListeningThreadUDP("UDP Listening thread",this); this.udp_connect_thread = new TListeningUDP("UDP Listening thread",this);
this.udp_connect_thread.start(); this.udp_connect_thread.start();
this.tcp_connect_thread = new ListeningThreadTCPConnection("TCP main Listening thread",this); this.tcp_connect_thread = new TListeningTCPConnection("TCP main Listening thread",this);
this.tcp_connect_thread.start(); this.tcp_connect_thread.start();
// Notification des utilisateurs distants // Notification des utilisateurs distants
@ -122,6 +125,7 @@ public class Controller {
try try
{ {
addIP = InetAddress.getLocalHost(); addIP = InetAddress.getLocalHost();
} }
catch(UnknownHostException e) { catch(UnknownHostException e) {
JOptionPane.showMessageDialog(null ,"Could not find local address!"); JOptionPane.showMessageDialog(null ,"Could not find local address!");
@ -133,10 +137,10 @@ public class Controller {
if(this.validatePseudo(pseudo)) { if(this.validatePseudo(pseudo)) {
this.udp_connect_thread = new ListeningThreadUDP("UDP Listening thread",this); this.udp_connect_thread = new TListeningUDP("UDP Listening thread",this);
this.udp_connect_thread.start(); this.udp_connect_thread.start();
this.tcp_connect_thread = new ListeningThreadTCPConnection("TCP main Listening thread",this); this.tcp_connect_thread = new TListeningTCPConnection("TCP main Listening thread",this);
this.tcp_connect_thread.start(); this.tcp_connect_thread.start();
@ -156,7 +160,39 @@ public class Controller {
} }
/*** GETTERS ***/
public LocalUser getMyUser() {
return myUser;
}
public Interface getview() {
return view;
}
public TListeningUDP getUdp_connect_thread() {
return udp_connect_thread;
}
public TListeningTCPConnection getTcp_connect_thread() {
return tcp_connect_thread;
}
public Historique getHistory() {
return histoire;
}
/*** SETTERS ***/
public void setMyUser(LocalUser myUser) {
this.myUser = myUser;
}
public void setview(Interface view) {
this.view = view;
}
public void setUdp_connect_thread(TListeningUDP udp_connect_thread) {
this.udp_connect_thread = udp_connect_thread;
}
public void setTcp_connect_thread(TListeningTCPConnection tcp_connect_thread) {
this.tcp_connect_thread = tcp_connect_thread;
}
public void setHistory(Historique histoire) {
this.histoire=histoire;
}
/**************************** Initialisation pseudo et découverte utilisateur distant (+notification utilisateurs distants) **********************************/ /**************************** Initialisation pseudo et découverte utilisateur distant (+notification utilisateurs distants) **********************************/
@ -222,7 +258,7 @@ public class Controller {
DatagramSocket dgramSocket = new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP()); DatagramSocket dgramSocket = new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP());
// Création du message à envoyer // Création du message à envoyer
String toSend = this.myUser.getAddIP()+":"+this.myUser.getPortUDPsend()+":info"; String toSend = this.myUser.getAddIP().getHostAddress()+":"+this.myUser.getPortUDPsend()+":info";
// Broadcast du message // Broadcast du message
broadcast(dgramSocket,toSend); broadcast(dgramSocket,toSend);
@ -255,7 +291,7 @@ public class Controller {
// On découpe la réponse en tableau de string ([adresseIP,tcpPort,nickname]) // On découpe la réponse en tableau de string ([adresseIP,tcpPort,nickname])
tabresponse = response.split(":"); tabresponse = response.split(":");
// Si reception on ajoute l'utilisateur à notre liste d'utilisateur distant // Si reception on ajoute l'utilisateur à notre liste d'utilisateur distant
this.myUser.addRemoteUser(InetAddress.getByName(tabresponse[0].split("/")[1]),Integer.parseInt(tabresponse[1]),tabresponse[2]); this.myUser.addRemoteUser(InetAddress.getByName(tabresponse[0]),Integer.parseInt(tabresponse[1]),tabresponse[2]);
valid= (tmpPseudo.compareTo(tabresponse[2])!=0); // On regarde la différence entre notre pseudo et le pseudo reçu valid= (tmpPseudo.compareTo(tabresponse[2])!=0); // On regarde la différence entre notre pseudo et le pseudo reçu
} }
newDate = new Date(); newDate = new Date();
@ -304,23 +340,8 @@ public class Controller {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
// Send to other active user (simulation of broadcast) // Send to other active user (simulation of broadcast)
String toSend = this.myUser.getAddIP().toString()+":"+this.myUser.getPortTCP()+":"+this.myUser.getPseudo()+":notify"; String toSend = this.myUser.getAddIP().getHostAddress()+":"+this.myUser.getPortTCP()+":"+this.myUser.getPseudo()+":notify";
/*
DatagramPacket outPacket =null;
int tabBroadcastSize = tabBroadcast.length;
for(int i=0;i<tabBroadcastSize;i++) {
if(tabBroadcast[i]!=myUser.getPortUDPlistening()) {
outPacket = new DatagramPacket(toSend.getBytes(), toSend.length(),this.myUser.getAddIP(), tabBroadcast[i]);
try {
dgramSocket.send(outPacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}*/
broadcast(dgramSocket,toSend); broadcast(dgramSocket,toSend);
dgramSocket.close(); dgramSocket.close();
} }
@ -347,15 +368,20 @@ public class Controller {
/*** recup history and put it in model ***/ /*** recup history and put it in model ***/
try { try {
//System.out.println(this.getHistory().retrieveMessage(getMyUser(), c.getRemoteUser())); try {
c.addListMessage(this.getHistory().retrieveMessage(getMyUser(), c.getRemoteUser())); c.addListMessage(this.getHistory().retrieveMessage(getMyUser(), c.getRemoteUser()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (SQLException e) { } catch (SQLException e) {
System.out.println("souci avec le retrieveMsg"); System.out.println("souci avec le retrieveMsgSQL");
e.printStackTrace(); e.printStackTrace();
} }
//System.out.println(myUser.getChats().get(myUser.getChatIndexOf(rm)));
return c; return c;
} }
public String askOpenSession(int index) { public String askOpenSession(int index) {
String history=""; String history="";
RemoteUser rm = myUser.getRemoteUsersList().get(index); RemoteUser rm = myUser.getRemoteUsersList().get(index);
@ -382,6 +408,10 @@ public class Controller {
return history; return history;
} }
public void askCloseSession() { public void askCloseSession() {
closeSession(this.activeChat); closeSession(this.activeChat);
this.activeChat = null; this.activeChat = null;
@ -431,13 +461,12 @@ public class Controller {
out.println(msg); out.println(msg);
} }
/*
public String askNewMessage() { public String askNewMessage() {
String message = ""; String message = "";
return message; return message;
} }*/
/**************************** Autre fonctions **********************************/
public String [] askUpdateActiveUsers() { public String [] askUpdateActiveUsers() {
String[] pseudotab = new String[myUser.getRemoteUsersList().size()]; String[] pseudotab = new String[myUser.getRemoteUsersList().size()];
@ -468,75 +497,52 @@ public class Controller {
Historique histoire=new Historique(); Historique histoire=new Historique();
/** Création des utilisateurs **/ /** Création des utilisateurs **/
// REMOTEUSER_1 - THEAU ArrayList<Controller> lstCtr = new ArrayList<Controller>();
Controller ctr1 = new Controller(31011,portUDPlistening_remoteUsr1,31021,"Theau",histoire);
// REMOTEUSER_2 - LEONIE
Controller ctr2 = new Controller(31012,portUDPlistening_remoteUsr2,31022,"Leonie",histoire);
// REMOTEUSER_3 - ALEXANDRE
Controller ctr3 = new Controller(31013,portUDPlistening_remoteUsr3,31023,"Alexandre",histoire);
// LOCAL USER - AS YOU WANT
Controller ctr = new Controller(31014,portUDPlistening_local,31024,histoire);
/** loop **/ // REMOTE USERS
Boolean running = ctr1.interfaceRunning || ctr2.interfaceRunning || ctr3.interfaceRunning || ctr.interfaceRunning; /*
Controller ctr1 = new Controller(31011,portUDPlistening_remoteUsr1,31021,"Theau",histoire);
lstCtr.add(ctr1);
Controller ctr2 = new Controller(31012,portUDPlistening_remoteUsr2,31022,"Leonie",histoire);
lstCtr.add(ctr2);
Controller ctr3 = new Controller(31013,portUDPlistening_remoteUsr3,31023,"Alexandre",histoire);
lstCtr.add(ctr3);
*/
// LOCAL USER
Controller ctr = new Controller(31014,portUDPlistening_local,31024,histoire);
lstCtr.add(ctr);
//Appel app=new Appel();
//app.test();
/** Loop **/
Boolean running = isRunning(lstCtr);
while(running) { while(running) {
running = ctr1.interfaceRunning || ctr2.interfaceRunning || ctr3.interfaceRunning || ctr.interfaceRunning; running = isRunning(lstCtr);
} }
System.out.println("Fin de la boucle"); System.out.println("Fin de la boucle");//TOREMOVE
/** End - Close thread and socket for every controller**/
closeThreads(lstCtr);
/** Close thread and socket **/
// REMOTEUSER_1 - THEAU
ctr1.close();
// REMOTEUSER_2 - LEONIE
ctr2.close();
// REMOTEUSER_3 - ALEXANDRE
ctr3.close();
// LOCAL USER
ctr.close();
// AFFICHAGE
System.out.println("end program"); System.out.println("end program");
JOptionPane.showMessageDialog(null ,"END"); JOptionPane.showMessageDialog(null ,"END");
} }
static boolean isRunning(ArrayList<Controller> lstCtr){
boolean isRunning=false;
/*** GETTERS ***/ for(Controller ctr : lstCtr) {
public LocalUser getMyUser() { isRunning|=ctr.interfaceRunning;
return myUser; }
} return isRunning;
public Interface getview() {
return view;
}
public ListeningThreadUDP getUdp_connect_thread() {
return udp_connect_thread;
}
public ListeningThreadTCPConnection getTcp_connect_thread() {
return tcp_connect_thread;
}
public Historique getHistory() {
return histoire;
} }
/*** SETTERS ***/ static void closeThreads(ArrayList<Controller> lstCtr) {
public void setMyUser(LocalUser myUser) { for(Controller ctr : lstCtr) {
this.myUser = myUser; ctr.close();
} }
public void setview(Interface view) {
this.view = view;
}
public void setUdp_connect_thread(ListeningThreadUDP udp_connect_thread) {
this.udp_connect_thread = udp_connect_thread;
}
public void setTcp_connect_thread(ListeningThreadTCPConnection tcp_connect_thread) {
this.tcp_connect_thread = tcp_connect_thread;
}
public void setHistory(Historique histoire) {
this.histoire=histoire;
} }
} }

View file

@ -18,7 +18,7 @@ import model.Msg_Text;
public class Historique { public class Historique {
public void saveMessage(model.User ctr1, model.RemoteUser ctr2, String input, String date) { public void saveMessage(model.User author, model.RemoteUser receiver, String input, String date) {
try { try {
Class.forName("java.sql.Driver"); Class.forName("java.sql.Driver");
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -46,7 +46,7 @@ public class Historique {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} }
/*
try { try {
nb_changed_rows = stat.executeUpdate("CREATE TABLE chat ( user_IPcode1 INTEGER, user_IPcode2 INTEGER ,Message VARCHAR(450) ,temps VARCHAR(450) )"); nb_changed_rows = stat.executeUpdate("CREATE TABLE chat ( user_IPcode1 INTEGER, user_IPcode2 INTEGER ,Message VARCHAR(450) ,temps VARCHAR(450) )");
}catch (Exception e) { }catch (Exception e) {
@ -54,9 +54,9 @@ public class Historique {
} }
System.out.println("coucou"); System.out.println("coucou");
*/
try { try {
nb_changed_rows = stat.executeUpdate("INSERT INTO chat VALUES ('"+ctr1.getIPcode()+"','"+ctr2.getIPcode()+"','"+input+"','"+date+"')"); nb_changed_rows = stat.executeUpdate("INSERT INTO chat VALUES ('"+author.getIPcode()+"','"+receiver.getIPcode()+"','"+input+"','"+date+"')");
} catch (SQLException e) { } catch (SQLException e) {
System.out.println("insertion pas établie"); System.out.println("insertion pas établie");
e.printStackTrace(); e.printStackTrace();
@ -82,106 +82,52 @@ public class Historique {
} }
public ArrayList<Message> retrieveMessage(model.LocalUser user1, model.RemoteUser user2) throws SQLException { public ArrayList<Message> retrieveMessage(model.LocalUser usr, model.RemoteUser rmusr) throws SQLException, ClassNotFoundException {
try { ArrayList<Message> messages=new ArrayList<Message>();
Class.forName("java.sql.Driver");
} catch (ClassNotFoundException e) { Class.forName("java.sql.Driver");
// TODO Auto-generated catch block
e.printStackTrace();
}
Connection con=DriverManager.getConnection("jdbc:mysql://srv-bdens.insa-toulouse.fr:3306","tp_servlet_003","povu3Ma2"); Connection con=DriverManager.getConnection("jdbc:mysql://srv-bdens.insa-toulouse.fr:3306","tp_servlet_003","povu3Ma2");
Statement stat = null; Statement stat = null;
try { stat = con.createStatement();
stat = con.createStatement(); stat.executeUpdate("USE tp_servlet_003");
} catch (SQLException e2) { /*
// TODO Auto-generated catch block
e2.printStackTrace();
}
Statement stat2 = null; Statement stat2 = null;
try { stat2 = con.createStatement();
stat2 = con.createStatement(); stat.executeUpdate("USE tp_servlet_003");
} catch (SQLException e1) { */
// TODO Auto-generated catch block
e1.printStackTrace();
}
int nb_changed_rows = stat.executeUpdate("USE tp_servlet_003");
try {
nb_changed_rows = stat.executeUpdate("USE TABLE chat ( user_IPcode1 INTEGER, user_IPcode2 INTEGER ,Message VARCHAR(450) ,temps VARCHAR(450) )");
}catch (Exception e) {
e.printStackTrace();
}
nb_changed_rows = stat2.executeUpdate("USE tp_servlet_003");
try {
nb_changed_rows = stat2.executeUpdate("USE TABLE chat ( user_IPcode1 INTEGER, user_IPcode2 INTEGER ,Message VARCHAR(450) ,temps VARCHAR(450) )");
}catch (Exception e) {
e.printStackTrace();
}
ResultSet RSSent=(stat.executeQuery("SELECT user_IPcode1, user_IPcode2, Message, temps FROM chat WHERE user_IPcode1="+user1.getIPcode()));
//System.out.println(RSSent);
boolean encore1 = RSSent.next();
ResultSet RSReceived=(stat2.executeQuery("SELECT user_IPcode1, user_IPcode2, Message, temps FROM chat WHERE user_IPcode1="+user2.getIPcode()));
boolean encore2 = RSReceived.next();
ArrayList<Message> message=new ArrayList<Message>();
//String message=null;
String[] string1=null;
String[] string2=null;
Calendar date1=Calendar.getInstance();
Calendar date2=Calendar.getInstance();
while(encore1 || encore2) {
//RSSent=(stat.executeQuery("SELECT user_IPcode1, user_IPcode2, Message, temps FROM chat WHERE user_IPcode1="+user1.getIPcode()));
//boolean temp=RSSent.next();
while (RSSent.getInt(2)!=user2.getIPcode()) {
encore1=RSSent.next();
}
string1=RSSent.getString(4).split(" ");
date1.set(Integer.valueOf(string1[0]), Integer.valueOf(string1[1]), Integer.valueOf(string1[2]),Integer.valueOf(string1[3]), Integer.valueOf(string1[4]), Integer.valueOf(string1[5]));
//RSReceived=(stat.executeQuery("SELECT user_IPcode1, user_IPcode2, Message, temps FROM chat WHERE user_IPcode1="+user2.getIPcode()));
//boolean tempi = RSReceived.next();
while (RSReceived.getInt(1)!=user1.getIPcode()) {
encore2=RSReceived.next();
}
string2=RSReceived.getString(4).split(" ");
date2.set(Integer.valueOf(string2[0]), Integer.valueOf(string2[1]), Integer.valueOf(string2[2]),Integer.valueOf(string2[3]), Integer.valueOf(string2[4]), Integer.valueOf(string2[5]));
if (date1.compareTo(date2)>=0) {
Msg_Text msg =new Msg_Text(user2,RSReceived.getString(4),RSReceived.getString(3));
message.add(msg);
Msg_Text msg1 =new Msg_Text(user1,RSSent.getString(4),RSSent.getString(3));
message.add(msg1);
}else {
Msg_Text msg1 =new Msg_Text(user1,RSSent.getString(4),RSSent.getString(3));
message.add(msg1);
Msg_Text msg =new Msg_Text(user2,RSReceived.getString(4),RSReceived.getString(3));
message.add(msg);
}
encore1=RSSent.next();
encore2=RSReceived.next();
}
RSSent.close();
RSReceived.close();
stat.close();
stat2.close();
con.close();
return message; //int nb_changed_rows;
String query = "SELECT user_IPcode1 ,Message, temps"
+" FROM chat WHERE (user_IPcode1="+usr.getIPcode()
+" AND user_IPcode2="+rmusr.getIPcode()+") "
+"OR (user_IPcode1="+rmusr.getIPcode()+" "
+ "AND user_IPcode2="+usr.getIPcode()+") "
+ "ORDER BY temps;";
ResultSet resultQueryRS=(stat.executeQuery(query));
int autorIPcode;
String message;
String strDate;
boolean encore = resultQueryRS.next();
while(encore) {
autorIPcode=resultQueryRS.getInt(1);
message=resultQueryRS.getString(2);;
strDate=resultQueryRS.getString(3);
if(usr.getIPcode()==autorIPcode) {
messages.add(new Msg_Text(usr,strDate,message));
}
else {
messages.add(new Msg_Text(rmusr,strDate,message));
}
encore=resultQueryRS.next();
}
return messages;
} }
// //MAIN
// public Historique() {
//
// System.out.println("coucoudb");
//
//
// }
} }

View file

@ -0,0 +1,141 @@
package controller;
import model.Chat;
import model.Msg_Text;
import model.RemoteUser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Calendar;
import java.util.Date;
public class TListeningTCPChat extends Thread{
protected Controller controller;
private Socket socket;
/* CONSTRUCTOR OF ListeningThreadTCPConnection
* @parametres
* @param s : String => nom du thread
* @param myUser : User => utilisateur utilisant ce thread
* @description
* <p>
* </p>
*/
public TListeningTCPChat(String s,Controller controller,Socket socket) {
this.controller = controller;
this.socket=socket;
}
/* run
* @description
* <p>
*
* </p>
*/
public void run() {
/**** function variables ****/
BufferedReader in = null;
String msg = null;
String input;
String dateString;
Date date;
Calendar date1=Calendar.getInstance();
Chat c = null;
try {
in =new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/************ Check rm user information **********/
// check data identification from rm user | TO REMOVE IF !=IP
int rmPortTCP = -1;
try {
rmPortTCP = Integer.parseInt(in.readLine());
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
RemoteUser rm = new RemoteUser("Unknown",this.socket.getInetAddress(),rmPortTCP);
int indexRM = controller.myUser.getActiveUserIndexOf(rm);
// Check if rm is identifiable
/*System.out.println(rm);
for(int i=0;i<controller.myUser.getRemoteUsersList().size();i++) {
System.out.println(controller.myUser.getRemoteUsersList().get(i));
}
System.out.println(indexRM);*/
if(indexRM!=-1) {
rm = controller.myUser.getRemoteUsersList().get(indexRM);
// Check if chat already created
int indexChat = controller.myUser.getChatIndexOf(rm);
if(indexChat!=-1) {
System.out.println("("+this.controller.myUser.getPseudo()+") Session déjà créer, on recupère le chat associé");
c = controller.myUser.getChats().get(indexChat);
}
else {
c=this.controller.openSession(rm);
}
/*** listening tcp message from rm until session is close ***/
try {
String msgToprint;
while (!(input=in.readLine()).equals("end")/* && c.getActive()*/) {
System.out.println("("+this.controller.myUser.getPseudo()+") recoit => "+rm.getPseudo()+" : "+input);
Msg_Text message = new Msg_Text(rm,input);
c.addMessage(message);
if(controller.activeChat==c) {
controller.view.notifyNewMessage("("+message.getDate()+")\n"+c.getRemoteUser().getPseudo()+" : "+input);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
System.out.println("("+this.controller.myUser.getPseudo()+") Remote User unidentifiable => CLOSING CONNECTION");
}
}
/* close
* @description
* <p>
* ferme le socket d'écoute TCP pour le chat
* interrupt TCP listening thread pour le chat
* </p>
*/
public void close() {
try {
this.socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("End of listing thread UDP ("+this.controller.myUser.getPseudo()+")");
try {
this.interrupt();
}catch (Exception e){
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,92 @@
package controller;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TListeningTCPConnection extends Thread{
protected Controller controller;
private Socket socket_tcp=null;
private int nbChat = 0;
/* CONSTRUCTOR OF ListeningThreadTCPConnection
* @parametres
* @param s : String => nom du thread
* @param myUser : User => utilisateur utilisant ce thread
* @description
* <p>
* </p>
*/
public TListeningTCPConnection(String s,Controller controller) {
this.controller = controller;
}
public void accept(ServerSocket servSocket) throws IOException {
Socket socket_tcp= servSocket.accept();
this.nbChat++;
TListeningTCPChat threadtcpchat = new TListeningTCPChat("Chat_of_"+controller.myUser.getPseudo()+"_"+nbChat,controller,socket_tcp);
threadtcpchat.start();
threadtcpchat.interrupt();
}
/* run
* @description
* <p>
* écoutes les messages TCP tant que l'utilisateur est actif
* Traitement
* Si réception d'une demande, créer un thread pour la conversation
* </p>
*/
public void run(){
// Tant que l'utilisateur est actif on attends la demande de nouvelle conversation
ServerSocket servSocket=null;
try {
servSocket = new ServerSocket(controller.myUser.getPortTCP());
System.out.println("("+this.controller.myUser.getPseudo()+") Server is listening on port "+this.controller.myUser.getPortTCP());
} catch (IOException e) {
System.out.println("("+this.controller.myUser.getPseudo()+") Server is not listening on port "+this.controller.myUser.getPortTCP());
e.printStackTrace();
}
while(true) {
System.out.println("("+this.controller.myUser.getPseudo()+") TCP Server waiting for new connection ...");
try {
this.accept(servSocket);
System.out.println("("+this.controller.myUser.getPseudo()+") NEW CONNECTION");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/* close
* @description
* <p>
* ferme le socket d'écoute TCO
* interrupt UDP listening threadS
* </p>
*/
public void close() {
try {
this.socket_tcp.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("End of listing thread TCP ("+this.controller.myUser.getPseudo()+")");
try {
this.interrupt();
}catch (Exception e){
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,125 @@
package controller;
import model.LocalUser;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TListeningUDP extends Thread{
protected Controller controller;
private DatagramSocket dgramSocket = null;
/* CONSTRUCTOR OF UserListeningThreadUDP
* @parametres
* @param s : String => nom du thread
* @param user : User => utilisateur utilisant ce thread
* @description
* <p>
* Appel du constructeur de la classe hérité
* Création d'un socket d'écoute UDP
* </p>
*/
public TListeningUDP(String s,Controller controller) {
this.controller = controller;
try {
this.dgramSocket = new DatagramSocket(this.controller.myUser.getPortUDPlistening(),this.controller.myUser.getAddIP());
} catch (IOException e) {
e.printStackTrace();
}
}
/* run
* @description
* <p>
* écoutes les messages UDP tant que l'utilisateur est actif
* Traitement
* 1) Si demande d'information => envoi ses informations
* 2) Si réception d'information => ajoute les informations
* </p>
*/
public void run(){
// Tant que l'utilisateur est actif on attends les messages des nouveaux utilisateurs et changements des utilisateurs actifs
while(true) {
// Réception du message
byte[] buffer = new byte[256];
DatagramPacket inPacket= new DatagramPacket(buffer, buffer.length);
try {
dgramSocket.receive(inPacket);
} catch (Exception e) {
e.printStackTrace();
}
buffer = inPacket.getData();
// Traitement en fonction du message reçu
String receiveMsg = new String(buffer);
String [] tabMsg = receiveMsg.split(":");
// si demande d'information d'un nouvel utilisateur
if(tabMsg.length==3) {
InetAddress itsIP = null;
try {
itsIP = InetAddress.getByName(tabMsg[0]); // On récupère l'adresse IP de l'utilisateur distant
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
int senderUDPport = Integer.parseInt(tabMsg[1]); // On récupère le port UDP de l'utilisateur distant
String toSend = controller.myUser.getAddIP().getHostAddress()+":"+controller.myUser.getPortTCP()+":"+controller.myUser.getPseudo()+":test";
DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),itsIP, senderUDPport);
try {
dgramSocket.send(outPacket);
} catch (IOException e) {
e.printStackTrace();
}
}
// Si un nouvel utilisateur passe en mode actif ou changement d'information
else {
try {
// On récupère l'adresse IP et le port TCP de l'utilisateur distant et ajout à la liste de l'utilisateur utilisant ce thread
controller.myUser.addRemoteUser(InetAddress.getByName(tabMsg[0]),Integer.parseInt(tabMsg[1]),tabMsg[2]);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(controller.interfaceRunning) {
controller.view.updateActiveUsers();
}
}
}
}
/* close
* @description
* <p>
* Ferme le socket d'écoute UDP
* Interrompt le thread d'écoute UDP
* </p>
*/
public void close() {
this.dgramSocket.close();
System.out.println("End of listing thread UDP ("+this.controller.myUser.getPseudo()+")");
try {
this.interrupt();
}catch (Exception e){
e.printStackTrace();
}
}
}

View file

@ -26,7 +26,7 @@ public abstract class User {
this.pseudo = pseudo; this.pseudo = pseudo;
this.addIP=addIP; this.addIP=addIP;
this.portTCP=portTCP; this.portTCP=portTCP;
this.IPcode=addIP.hashCode(); this.IPcode=hashCode();
} }
@ -57,6 +57,15 @@ public abstract class User {
} }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
String ip=addIP.getHostAddress();
result = prime * result + ((ip == null) ? 0 : ip.hashCode());
result = prime * result + portTCP;
return result;
}
@Override @Override
@ -68,11 +77,29 @@ public abstract class User {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
User other = (User) obj; User other = (User) obj;
if (addIP == null) {
if (other.addIP != null)
return false;
} else if (!addIP.equals(other.addIP))
return false;
if (portTCP != other.portTCP) if (portTCP != other.portTCP)
return false; return false;
return true; return true;
} }
@Override
public String toString() {
return "User [pseudo=" + pseudo + ", addIP=" + addIP.getHostAddress() + ", portTCP=" + portTCP + ", IPcode=" + IPcode + "]";
}

View file

@ -0,0 +1,39 @@
package websocket;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
public class Appel {
private WebSocketContainer container;
private Client client;
public void test() {
this.container= ContainerProvider.getWebSocketContainer();
this.client=new Client();
Session session=null;
try {
session=this.container.connectToServer(this.client, new URI ("ws://localhost:8082/WebSocket2/hello"));
} catch (DeploymentException | IOException | URISyntaxException e) {
e.printStackTrace();
System.out.println("pb avec le connect");
}
try {
this.client.onOpen(session, null);
this.client.sendMessage("hello from client");
} catch (IOException e) {
System.out.println("pb avec le sendMessage");
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,5 @@
package websocket;
public class Centralized {
}

View file

@ -0,0 +1,26 @@
package websocket;
import java.io.IOException;
import javax.websocket.*;
public class Client extends Endpoint{
private Session session;
@Override
public void onOpen (Session session, EndpointConfig config) {
this.session=session;
this.session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage (String msg) {
System.out.println("msg recu:"+msg);
};}
);
}
public void sendMessage(String msg) throws IOException {
this.session.getBasicRemote().sendText(msg);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

BIN
Executable/Client_31024.jar Normal file

Binary file not shown.

BIN
Executable/Leonie_31022.jar Normal file

Binary file not shown.

BIN
Executable/Theau_31021.jar Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
Final_Sequence_Diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View file

@ -4,4 +4,49 @@ SYSTEME DE CLAVARDAGE DISTRIBUE INTERACTIF MULTI-UTILISATEUR TEMPS REEL
4IR A2 4IR A2
Alexandre Gonzalvez Alexandre Gonzalvez
Théau Giraud Théau Giraud
Léonie Gallois Léonie Gallois
*************Manuel dinstallation & dutilisation de lapplication*************
Ce manuel est aussi disponible dans le rapport, notamment avec des images pour la partie utilisation. Nous vous conseillons aussi vivement de regarder la vidéo explicative se trouvant dans le même repository que ce fichier.
Etape 1: Télécharger le projet via GitEtud
Tout dabord, allez sur le GitEtud de LINSA Toulouse à cette adresse: https://git.etud.insa-toulouse.fr/gallois/Clavardage. Notre projet sappelle Clavardage, vous pouvez effectuer un pull à partir de la branche master. (Dautres versions du projet sont également disponibles, par exemple la branche v1 ne nécessite aucune installation supplémentaire mais ne gère pas la récupération de lhistorique).
Etape 2: Télécharger MySQL Workbench
Ensuite, pour faire le lien avec notre base de données, il vous faudra installer MySQL Workbench et ConnectorJ. MySQL est gratuit et répond bien à nos besoins pour la base de données. Voici un lien vers la page de téléchargement: https://dev.mysql.com/downloads/workbench/.
Vous remarquerez que la page web suivante vous demande un login. Il nest pas obligatoire. Vous pouvez directement cliquer sur “No thanks, just start my download” en bas de la page et télécharger MySQL sans compte. Dans le setup MySQL il vous faudra télécharger seulement le Workbench et le ConnectorJ.
Il ny a ensuite pas de manipulations à faire avec MySQL. La connexion avec la base de données a déjà été mise en place dans le code de lapplication et du côté du serveur.
Etape 3: Connexion au VPN de LINSA
Si vous utilisez une machine se situant à lINSA vous pouvez passer cette étape. Sinon, il vous faudra vous connecter au réseau de lINSA en utilisant un VPN pour faire marcher la base de données qui utilise ce réseau. Voici le lien vers la page du CSN expliquant sa mise en place: http://csn.insa-toulouse.fr/fr/services/services-transverses/connexion-par-vpn.html.
Etape 4: Lancement et utilisation de lapplication
Vérifiez bien dêtre connecté au VPN avant de tester lapplication. Comme dans la vidéo explicative (que nous vous conseillons et qui est elle aussi sur le git), vous avez juste à ouvrir le fichier Client.jar dans le répertoire Executable ainsi quun ou plusieurs des .jar utilisateurs distants.
Quand vous ouvrez lapplication, une fenêtre apparaît vous demandant votre Pseudo. Vous recevrez un message de confirmation avec votre Pseudo affiché ou un message derreur sil nest pas valide.
Linterface souvrira ensuite. Vous pourrez changer votre Pseudo dans la barre de texte à côté de “Change nickname:”. Les mêmes messages de confirmation/derreur apparaîtront.
Ensuite, pour commencer un chat avec un des autres utilisateurs, cliquez sur la flèche du menu déroulant répertoriant leurs noms. Double-cliquez sur un utilisateur et un message de confirmation souvrira.
Une fenêtre de chat vide souvre. Vous pouvez y taper vos messages et les envoyer.
Pour visualiser larrivée des messages, établissez la connexion en faisant la même manip sur linterface de lutilisateur distant avec lequel vous communiquez. Vous verrez ici quun chat existant déjà, une fenêtre souvre en disant que lon va chercher les messages envoyés qui ont été stockés dans la base de données.
Les messages envoyés sont récupérés et sont affichés dans la fenêtre chat de lutilisateur distant. Vous pouvez aussi changer encore une fois les pseudos et voir que les messages envoyés après le changement de pseudo sont marqués avec celui-ci.
Pour fermer le chat, cliquez sur le bouton “Close session”.
Vous pouvez aussi fermer les applications entièrement en cliquant sur la croix rouge en haut à droite. En rouvrant une nouvelle instance de lapplication, vous pouvez (notamment avec un pseudo différent si cela vous chante, votre adresse sera quand même reconnue) relancer un chat avec lutilisateur précédent. Les messages ayant été stockés dans la base de données, ils seront récupérés et affichés tels qu'ils avaient été envoyés.
*************Fin du manuel dinstallation & dutilisation de lapplication*************

BIN
Rapport COO.pdf Normal file

Binary file not shown.

BIN
Rapport POO.pdf Normal file

Binary file not shown.

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RemoteSystemsTempFiles</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
<nature>org.eclipse.rse.ui.remoteSystemsTempNature</nature>
</natures>
</projectDescription>

34
Server.java Normal file
View file

@ -0,0 +1,34 @@
package websocket;
import javax.websocket.server.*;
import java.io.IOException;
import javax.websocket.*;
@ServerEndpoint("/hello/")
public class Server {
private Session session;
@OnOpen
public void connect(Session session) {
this.session= session;
System.out.println("session :"+ session);
}
@OnClose
public void close() {
this.session=null;
System.out.println("session closed");
}
@OnMessage
public void onMessage(String msg) throws IOException {
System.out.println("msg recu:"+msg);
this.session.getAsyncRemote().sendText("server:"+msg);
//if (this.session != null && this.session.isOpen()) {
// this.session.getBasicRemote().sendText("server:"+msg);
//}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.