Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
82f3cbd91f | |||
42f8d92b9d | |||
0c7bcb7b51 | |||
a33aeb87ed | |||
6917a454e7 | |||
a9fa3e3ef4 | |||
0ca69de2c3 | |||
d8557a852f | |||
772c039b51 |
53 changed files with 2315 additions and 4870 deletions
14
Application/Clavardage/.classpath
Normal file
14
Application/Clavardage/.classpath
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<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="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"/>
|
||||||
|
</classpath>
|
17
Application/Clavardage/.project
Normal file
17
Application/Clavardage/.project
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>Clavardage</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
11
Application/Clavardage/.settings/org.eclipse.jdt.core.prefs
Normal file
11
Application/Clavardage/.settings/org.eclipse.jdt.core.prefs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.8
|
2
Application/Clavardage/bin/.gitignore
vendored
Normal file
2
Application/Clavardage/bin/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/websocket/
|
||||||
|
/controller/
|
BIN
Application/Clavardage/bin/model/Chat.class
Normal file
BIN
Application/Clavardage/bin/model/Chat.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/model/LocalUser.class
Normal file
BIN
Application/Clavardage/bin/model/LocalUser.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/model/Message.class
Normal file
BIN
Application/Clavardage/bin/model/Message.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/model/Msg_Text.class
Normal file
BIN
Application/Clavardage/bin/model/Msg_Text.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/model/RemoteUser.class
Normal file
BIN
Application/Clavardage/bin/model/RemoteUser.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/model/User.class
Normal file
BIN
Application/Clavardage/bin/model/User.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/view/Interface$1.class
Normal file
BIN
Application/Clavardage/bin/view/Interface$1.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/view/Interface$2.class
Normal file
BIN
Application/Clavardage/bin/view/Interface$2.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/view/Interface$3.class
Normal file
BIN
Application/Clavardage/bin/view/Interface$3.class
Normal file
Binary file not shown.
BIN
Application/Clavardage/bin/view/Interface.class
Normal file
BIN
Application/Clavardage/bin/view/Interface.class
Normal file
Binary file not shown.
550
Application/Clavardage/src/controller/Controller.java
Normal file
550
Application/Clavardage/src/controller/Controller.java
Normal file
|
@ -0,0 +1,550 @@
|
||||||
|
package controller;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
//import javax.websocket.DeploymentException;
|
||||||
|
|
||||||
|
import model.Chat;
|
||||||
|
import model.LocalUser;
|
||||||
|
import model.Message;
|
||||||
|
import model.Msg_Text;
|
||||||
|
import model.RemoteUser;
|
||||||
|
import view.Interface;
|
||||||
|
//import websocket.Appel;
|
||||||
|
|
||||||
|
public class Controller {
|
||||||
|
|
||||||
|
/*** CONSTANTES ***/
|
||||||
|
final int NB_SECOND_WAITING_RESPONSE_BROADCAST = 1;
|
||||||
|
|
||||||
|
// TO REMOVE when we use broadcast
|
||||||
|
final static int portUDPlistening_remoteUsr1 = 31001;
|
||||||
|
final static int portUDPlistening_remoteUsr2 = 31002;
|
||||||
|
final static int portUDPlistening_remoteUsr3 = 31003;
|
||||||
|
final static int portUDPlistening_local = 31004;
|
||||||
|
final static int [] tabBroadcast = {portUDPlistening_remoteUsr1,portUDPlistening_remoteUsr2,portUDPlistening_remoteUsr3,portUDPlistening_local};
|
||||||
|
|
||||||
|
public Boolean interfaceRunning = false;
|
||||||
|
/*** ATTRIBUTS ***/
|
||||||
|
protected LocalUser myUser;
|
||||||
|
protected Interface view;
|
||||||
|
private TListeningUDP udp_connect_thread;
|
||||||
|
private TListeningTCPConnection tcp_connect_thread;
|
||||||
|
private Historique histoire;
|
||||||
|
protected Chat activeChat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of Controller
|
||||||
|
* @parametres
|
||||||
|
* @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 portTCP : int => le numéro de port pour commencer une nouvelle conversation
|
||||||
|
* @throws IOException
|
||||||
|
* @descrition
|
||||||
|
* <p>
|
||||||
|
* On récupère l'adresse de la machine, on demande un pseudo à l'utilisateur que l'on vérifie
|
||||||
|
* Une fois validé l'utilisateur devient actif :
|
||||||
|
* - écoute UDP pour les pseudos
|
||||||
|
* - écoute TCP pour de nouvelles conversation
|
||||||
|
* - notification aux autres utilisateurs actifs
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
private Controller(int portUDPsend,int portUDPlistening,int portTCP,Historique histoire) throws IOException {
|
||||||
|
this.histoire= histoire;
|
||||||
|
|
||||||
|
// Récupération de l'adresse IP local
|
||||||
|
InetAddress addIP = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addIP = InetAddress.getLocalHost();
|
||||||
|
}
|
||||||
|
catch(UnknownHostException e) {
|
||||||
|
JOptionPane.showMessageDialog(null ,"Could not find local address!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création de l'utilisateur
|
||||||
|
this.myUser = new LocalUser("Unknown",addIP,portUDPsend,portUDPlistening,portTCP);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.myUser.setPseudo(this.initPseudo()); // Initialisation du pseudo manuel
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création des threads d'écoutes
|
||||||
|
this.udp_connect_thread = new TListeningUDP("UDP Listening thread",this);
|
||||||
|
this.udp_connect_thread.start();
|
||||||
|
this.tcp_connect_thread = new TListeningTCPConnection("TCP main Listening thread",this);
|
||||||
|
this.tcp_connect_thread.start();
|
||||||
|
|
||||||
|
// Notification des utilisateurs distants
|
||||||
|
notify_remote_users();
|
||||||
|
|
||||||
|
// Création de l'interface
|
||||||
|
interfaceRunning =true;
|
||||||
|
view=Interface.createAndShowGUI(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of Controller
|
||||||
|
* @parametres
|
||||||
|
* @param portUDPsend : int => le numéro de port pour envoyé 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 portTCP : int => le numéro de port pour commencer une nouvelle conversation
|
||||||
|
* @descrition
|
||||||
|
* <p>
|
||||||
|
* On récupère l'adresse de la machine, on demande un pseudo à l'utilisateur que l'on vérifie
|
||||||
|
* Une fois validé l'utilisateur devient actif :
|
||||||
|
* - écoute UDP pour les pseudos
|
||||||
|
* - écoute TCP pour de nouvelles conversation
|
||||||
|
* - notification aux autres utilisateurs actifs
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
private Controller(int portUDPsend,int portUDPlistening,int portTCP,String pseudo,Historique histoire) throws IOException{
|
||||||
|
|
||||||
|
this.histoire=histoire;
|
||||||
|
|
||||||
|
// Récupération de l'adresse IP local
|
||||||
|
InetAddress addIP = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addIP = InetAddress.getLocalHost();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(UnknownHostException e) {
|
||||||
|
JOptionPane.showMessageDialog(null ,"Could not find local address!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création de l'utilisateur
|
||||||
|
this.myUser = new LocalUser(pseudo,addIP,portUDPsend,portUDPlistening,portTCP);
|
||||||
|
try {
|
||||||
|
if(this.validatePseudo(pseudo)) {
|
||||||
|
|
||||||
|
|
||||||
|
this.udp_connect_thread = new TListeningUDP("UDP Listening thread",this);
|
||||||
|
this.udp_connect_thread.start();
|
||||||
|
|
||||||
|
this.tcp_connect_thread = new TListeningTCPConnection("TCP main Listening thread",this);
|
||||||
|
this.tcp_connect_thread.start();
|
||||||
|
|
||||||
|
|
||||||
|
// Notification des utilisateurs distants
|
||||||
|
notify_remote_users();
|
||||||
|
|
||||||
|
// Création de l'interface
|
||||||
|
interfaceRunning =true;
|
||||||
|
view=Interface.createAndShowGUI(this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("Unavailable "+pseudo);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** 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) **********************************/
|
||||||
|
|
||||||
|
/** initPseudo
|
||||||
|
* <p>
|
||||||
|
* Demande à l'utilisateur de rentrer un pseudo et valide de ce dernier en demandant aux
|
||||||
|
* utilisateurs distants leurs informations
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public String initPseudo() throws IOException {
|
||||||
|
String tmpPseudo = JOptionPane.showInputDialog(null, "Enter nickname:"); // Read user input
|
||||||
|
|
||||||
|
while(!(this.validatePseudo(tmpPseudo))) { // On demande aux autres utilisateurs de nous envoyer leurs informations et on test si le pseudo est déjà utilisé
|
||||||
|
tmpPseudo = JOptionPane.showInputDialog(null, "Enter another nickname:"); // Read user input
|
||||||
|
}
|
||||||
|
|
||||||
|
//sc1.close();
|
||||||
|
JOptionPane.showMessageDialog(null ,"Your nickname : " + tmpPseudo + " is valid !");
|
||||||
|
|
||||||
|
return tmpPseudo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** changePseudo
|
||||||
|
* <p>
|
||||||
|
* Demande à l'utilisateur de rentrer un pseudo et valide de ce dernier en demandant aux
|
||||||
|
* utilisateurs distants leurs informations.
|
||||||
|
* On regarde si le pseudo est bien différent de l'ancien
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void changePseudo() throws IOException {
|
||||||
|
String oldPseudo = this.myUser.getPseudo(); //Saves the old one for comparison
|
||||||
|
|
||||||
|
String tmpPseudo = view.ChangePseudotextField.getText(); // Read user input
|
||||||
|
|
||||||
|
if(!(this.validatePseudo(tmpPseudo)) || tmpPseudo.equals(oldPseudo)) {
|
||||||
|
view.Pseudolabel.setText("Already exists, enter another nickname. Your current username is: " + oldPseudo); // Read user input
|
||||||
|
tmpPseudo = view.ChangePseudotextField.getText(); // Read user input
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.myUser.setPseudo(tmpPseudo);
|
||||||
|
JOptionPane.showMessageDialog(null ,"Your new nickname : " + tmpPseudo + " is valid !");
|
||||||
|
this.notify_remote_users();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** validatePseudo
|
||||||
|
* <p>
|
||||||
|
* *tmpPseudo : String => Le pseudo à valider
|
||||||
|
*</p><p>
|
||||||
|
* Envoi en broadcast (pour l'instant envoi sur les ports de notre ordinateur) d'une demande d'information
|
||||||
|
*</p><p>
|
||||||
|
* On attend les réponses pendant 5 secondes
|
||||||
|
*</p><p>
|
||||||
|
* On valide le pseudo en fonction des pseudos reçu
|
||||||
|
*</p><p>
|
||||||
|
* On en profite pour ajouter les utilisateurs répondant à notre liste d'utilisateur distant (RemoteUser)
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public Boolean validatePseudo(String tmpPseudo) throws IOException {
|
||||||
|
Boolean valid = true;
|
||||||
|
|
||||||
|
DatagramSocket dgramSocket = new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP());
|
||||||
|
|
||||||
|
// Création du message à envoyer
|
||||||
|
String toSend = this.myUser.getAddIP().getHostAddress()+":"+this.myUser.getPortUDPsend()+":info";
|
||||||
|
|
||||||
|
// Broadcast du message
|
||||||
|
broadcast(dgramSocket,toSend);
|
||||||
|
|
||||||
|
/*** For 5 seconds wait for answer : validate pseudo & add to userlist ***/
|
||||||
|
byte[] buffer = new byte[256];
|
||||||
|
DatagramPacket inPacket;
|
||||||
|
String response = null;
|
||||||
|
String[] tabresponse= new String [4];
|
||||||
|
dgramSocket.setSoTimeout(1000);
|
||||||
|
Boolean arecu;
|
||||||
|
int nbReponse =0;
|
||||||
|
System.out.println("("+myUser.getPseudo()+") Waiting for pseudo validation ...");
|
||||||
|
Date oldDate = new Date();
|
||||||
|
Date newDate = new Date();
|
||||||
|
|
||||||
|
while( (newDate.getTime()-oldDate.getTime()) < NB_SECOND_WAITING_RESPONSE_BROADCAST*1000 && valid) {
|
||||||
|
nbReponse++;
|
||||||
|
inPacket= new DatagramPacket(buffer, buffer.length);
|
||||||
|
arecu=true;
|
||||||
|
try{
|
||||||
|
dgramSocket.receive(inPacket);
|
||||||
|
}catch (Exception e) {
|
||||||
|
arecu=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = inPacket.getData();
|
||||||
|
response = new String(buffer);
|
||||||
|
if(arecu) {
|
||||||
|
// On découpe la réponse en tableau de string ([adresseIP,tcpPort,nickname])
|
||||||
|
tabresponse = response.split(":");
|
||||||
|
// Si reception on ajoute l'utilisateur à notre liste d'utilisateur distant
|
||||||
|
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
|
||||||
|
}
|
||||||
|
newDate = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dgramSocket.close();
|
||||||
|
if(!valid) {
|
||||||
|
JOptionPane.showMessageDialog(null ,"Nickname : "+tmpPseudo +" is taken !");
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***broadcast
|
||||||
|
*
|
||||||
|
* @param dgramSocket
|
||||||
|
* @param toSend
|
||||||
|
* @param broadcastIP
|
||||||
|
* @throws IOException
|
||||||
|
* <p>
|
||||||
|
* Simulation of broadcast with port given (tabBroadcast)
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public void broadcast(DatagramSocket dgramSocket,String toSend) throws IOException {
|
||||||
|
InetAddress broadcastIP = InetAddress.getLocalHost();
|
||||||
|
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(),broadcastIP, tabBroadcast[i]);
|
||||||
|
dgramSocket.send(outPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** notify_remote_users
|
||||||
|
* <p>
|
||||||
|
* En utilisant le port UDP d'envoi, on envoie en broadcast les informations nous concernant
|
||||||
|
* </p>
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void notify_remote_users() throws IOException {
|
||||||
|
DatagramSocket dgramSocket= null;
|
||||||
|
try {
|
||||||
|
dgramSocket= new DatagramSocket(this.myUser.getPortUDPsend(),this.myUser.getAddIP());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// Send to other active user (simulation of broadcast)
|
||||||
|
String toSend = this.myUser.getAddIP().getHostAddress()+":"+this.myUser.getPortTCP()+":"+this.myUser.getPseudo()+":notify";
|
||||||
|
broadcast(dgramSocket,toSend);
|
||||||
|
dgramSocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************** Gestion des sessions **********************************/
|
||||||
|
|
||||||
|
public Chat openSession(RemoteUser rm) {
|
||||||
|
Chat c = myUser.addChats(rm); // Create chat and add it to myUser
|
||||||
|
|
||||||
|
/*** Create socket send => ask connection to server of rm ***/
|
||||||
|
Socket link=null;
|
||||||
|
try {
|
||||||
|
// Connection => server tcp rm
|
||||||
|
System.out.println("("+this.myUser.getPseudo()+") Connecting to "+c.getRemoteUser().getPortTCP()+" of " + c.getRemoteUser().getPseudo());
|
||||||
|
link=new Socket(c.getRemoteUser().getAddIP(),c.getRemoteUser().getPortTCP()/*, InetAddress.getLocalHost() ,myUser.getPortTCP()*/);
|
||||||
|
c.setSocket(link);
|
||||||
|
// Sending data for identification (TO REMOVE IF != IP)
|
||||||
|
sendInfoProcess(Integer.toString(myUser.getPortTCP()), c); // tell rm session STOP
|
||||||
|
}catch(IOException e) {
|
||||||
|
System.out.println("Error linking to TCP server of "+ c.getRemoteUser().getPortTCP());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** recup history and put it in model ***/
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
c.addListMessage(this.getHistory().retrieveMessage(getMyUser(), c.getRemoteUser()));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("souci avec le retrieveMsgSQL");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String askOpenSession(int index) {
|
||||||
|
String history="";
|
||||||
|
RemoteUser rm = myUser.getRemoteUsersList().get(index);
|
||||||
|
Chat c;
|
||||||
|
|
||||||
|
/*** Recup or create chat ***/
|
||||||
|
if(myUser.getChatIndexOf(rm)!=-1) { // if already a chat open
|
||||||
|
c = myUser.getChats().get(myUser.getChatIndexOf(rm));
|
||||||
|
JOptionPane.showMessageDialog(null ,"Active session with "+c.getRemoteUser().getPseudo()+" loading history");
|
||||||
|
}
|
||||||
|
else { // else create it
|
||||||
|
c=openSession(rm);
|
||||||
|
JOptionPane.showMessageDialog(null ,"New session with "+rm.getPseudo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for history
|
||||||
|
|
||||||
|
int nbMessage = c.getMessages().size();
|
||||||
|
for(int i=0;i<nbMessage;i++) {
|
||||||
|
history+="\n("+c.getMessages().get(i).getDate()+")\n"+c.getMessages().get(i).getAutor().getPseudo()+" : "+c.getMessages().get(i).getMessage();
|
||||||
|
}
|
||||||
|
this.activeChat = c;
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void askCloseSession() {
|
||||||
|
closeSession(this.activeChat);
|
||||||
|
this.activeChat = null;
|
||||||
|
}
|
||||||
|
public void closeSession(Chat c) {
|
||||||
|
sendInfoProcess("end", c); // tell rm session STOP
|
||||||
|
JOptionPane.showMessageDialog(null ,"Close session with "+c.getRemoteUser().getPseudo());
|
||||||
|
this.myUser.closeChat(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************** Gestion des messages **********************************/
|
||||||
|
|
||||||
|
public void askToSend(String textMessage){
|
||||||
|
sendMessage(new Msg_Text(myUser,textMessage), this.activeChat);
|
||||||
|
}
|
||||||
|
public void sendMessage(Message msg,Chat c) {
|
||||||
|
/*** Init send process ***/
|
||||||
|
PrintWriter out=null;
|
||||||
|
try {
|
||||||
|
out = new PrintWriter(c.getUserSocket().getOutputStream(),true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
c.addMessage(msg);
|
||||||
|
|
||||||
|
// TODO check if instance of Msg_Text or anything else and threat it given a type
|
||||||
|
String message = (String) msg.getMessage();
|
||||||
|
|
||||||
|
// Sauvegarde dans la base de données
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy MM dd HH mm ss");
|
||||||
|
Date date=new Date();
|
||||||
|
this.getHistory().saveMessage(getMyUser(), c.getRemoteUser(),message ,dateFormat.format(date));
|
||||||
|
|
||||||
|
// Send message
|
||||||
|
out.println(message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendInfoProcess(String msg,Chat c) {
|
||||||
|
PrintWriter out=null;
|
||||||
|
try {
|
||||||
|
out = new PrintWriter(c.getUserSocket().getOutputStream(),true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.println(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public String askNewMessage() {
|
||||||
|
String message = "";
|
||||||
|
return message;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
public String [] askUpdateActiveUsers() {
|
||||||
|
String[] pseudotab = new String[myUser.getRemoteUsersList().size()];
|
||||||
|
int size = myUser.getRemoteUsersList().size();
|
||||||
|
for(int i=0; i < size; i++) {
|
||||||
|
pseudotab[i] = myUser.getRemoteUsersList().get(i).getPseudo();
|
||||||
|
}
|
||||||
|
return pseudotab;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void askForClose() {
|
||||||
|
interfaceRunning = false;
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
public void close() {
|
||||||
|
if(interfaceRunning) {
|
||||||
|
myUser.closeAllChat();
|
||||||
|
tcp_connect_thread.close();
|
||||||
|
udp_connect_thread.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
System.out.println("start program");
|
||||||
|
|
||||||
|
Historique histoire=new Historique();
|
||||||
|
|
||||||
|
/** Création des utilisateurs **/
|
||||||
|
ArrayList<Controller> lstCtr = new ArrayList<Controller>();
|
||||||
|
|
||||||
|
// REMOTE USERS
|
||||||
|
/*
|
||||||
|
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) {
|
||||||
|
running = isRunning(lstCtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Fin de la boucle");//TOREMOVE
|
||||||
|
|
||||||
|
/** End - Close thread and socket for every controller**/
|
||||||
|
closeThreads(lstCtr);
|
||||||
|
System.out.println("end program");
|
||||||
|
JOptionPane.showMessageDialog(null ,"END");
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isRunning(ArrayList<Controller> lstCtr){
|
||||||
|
boolean isRunning=false;
|
||||||
|
for(Controller ctr : lstCtr) {
|
||||||
|
isRunning|=ctr.interfaceRunning;
|
||||||
|
}
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void closeThreads(ArrayList<Controller> lstCtr) {
|
||||||
|
for(Controller ctr : lstCtr) {
|
||||||
|
ctr.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
133
Application/Clavardage/src/controller/Historique.java
Normal file
133
Application/Clavardage/src/controller/Historique.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package controller;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import javax.sql.rowset.JdbcRowSet;
|
||||||
|
|
||||||
|
import model.Message;
|
||||||
|
import model.Msg_Text;
|
||||||
|
|
||||||
|
public class Historique {
|
||||||
|
|
||||||
|
public void saveMessage(model.User author, model.RemoteUser receiver, String input, String date) {
|
||||||
|
try {
|
||||||
|
Class.forName("java.sql.Driver");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Connection con = null;
|
||||||
|
try {
|
||||||
|
con = DriverManager.getConnection("jdbc:mysql://srv-bdens.insa-toulouse.fr:3306","tp_servlet_003","povu3Ma2");
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
Statement stat = null;
|
||||||
|
try {
|
||||||
|
stat = con.createStatement();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
int nb_changed_rows = 0;
|
||||||
|
try {
|
||||||
|
nb_changed_rows = stat.executeUpdate("USE tp_servlet_003");
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
try {
|
||||||
|
nb_changed_rows = stat.executeUpdate("CREATE TABLE chat ( user_IPcode1 INTEGER, user_IPcode2 INTEGER ,Message VARCHAR(450) ,temps VARCHAR(450) )");
|
||||||
|
}catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("coucou");
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
nb_changed_rows = stat.executeUpdate("INSERT INTO chat VALUES ('"+author.getIPcode()+"','"+receiver.getIPcode()+"','"+input+"','"+date+"')");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("insertion pas établie");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// try {
|
||||||
|
// nb_changed_rows = stat.executeUpdate("DELETE FROM chat WHERE data(VARCHAR(255))="valeur"");
|
||||||
|
// } catch (SQLException e) {
|
||||||
|
// // TODO Auto-generated catch block
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
try {
|
||||||
|
stat.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
con.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Message> retrieveMessage(model.LocalUser usr, model.RemoteUser rmusr) throws SQLException, ClassNotFoundException {
|
||||||
|
ArrayList<Message> messages=new ArrayList<Message>();
|
||||||
|
|
||||||
|
Class.forName("java.sql.Driver");
|
||||||
|
Connection con=DriverManager.getConnection("jdbc:mysql://srv-bdens.insa-toulouse.fr:3306","tp_servlet_003","povu3Ma2");
|
||||||
|
Statement stat = null;
|
||||||
|
stat = con.createStatement();
|
||||||
|
stat.executeUpdate("USE tp_servlet_003");
|
||||||
|
/*
|
||||||
|
Statement stat2 = null;
|
||||||
|
stat2 = con.createStatement();
|
||||||
|
stat.executeUpdate("USE tp_servlet_003");
|
||||||
|
*/
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
16
Application/Clavardage/src/controller/ListeningThread.java
Normal file
16
Application/Clavardage/src/controller/ListeningThread.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package controller;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class ListeningThread extends Thread{
|
||||||
|
|
||||||
|
protected Controller controller;
|
||||||
|
|
||||||
|
public ListeningThread(String s,Controller controller) {
|
||||||
|
super(s);
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void run();
|
||||||
|
|
||||||
|
public abstract void close();
|
||||||
|
}
|
|
@ -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 ListeningThreadTCPChat extends ListeningThread{
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
|
||||||
|
/* CONSTRUCTOR OF ListeningThreadTCPConnection
|
||||||
|
* @parametres
|
||||||
|
* @param s : String => nom du thread
|
||||||
|
* @param myUser : User => utilisateur utilisant ce thread
|
||||||
|
* @description
|
||||||
|
* <p>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public ListeningThreadTCPChat(String s,Controller controller,Socket socket) {
|
||||||
|
super(s,controller);
|
||||||
|
this.socket=socket;
|
||||||
|
// TODO OpenSession si ouverture exterieur
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package controller;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class ListeningThreadTCPConnection extends ListeningThread{
|
||||||
|
|
||||||
|
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 ListeningThreadTCPConnection(String s,Controller controller) {
|
||||||
|
super(s,controller);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void accept(ServerSocket servSocket) throws IOException {
|
||||||
|
Socket socket_tcp= servSocket.accept();
|
||||||
|
this.nbChat++;
|
||||||
|
ListeningThreadTCPChat threadtcpchat = new ListeningThreadTCPChat("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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
124
Application/Clavardage/src/controller/ListeningThreadUDP.java
Normal file
124
Application/Clavardage/src/controller/ListeningThreadUDP.java
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
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 ListeningThreadUDP extends ListeningThread{
|
||||||
|
|
||||||
|
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 ListeningThreadUDP(String s,Controller controller) {
|
||||||
|
super(s,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].split("/")[1]); // 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().toString()+":"+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].split("/")[1]),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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
Application/Clavardage/src/controller/TListeningTCPChat.java
Normal file
141
Application/Clavardage/src/controller/TListeningTCPChat.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
125
Application/Clavardage/src/controller/TListeningUDP.java
Normal file
125
Application/Clavardage/src/controller/TListeningUDP.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
Application/Clavardage/src/model/Chat.java
Normal file
69
Application/Clavardage/src/model/Chat.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Chat {
|
||||||
|
|
||||||
|
/*** ATTRIBUTS ***/
|
||||||
|
private RemoteUser remoteUser;
|
||||||
|
private ArrayList<Message> messages = new ArrayList<Message>();
|
||||||
|
private Socket userSocket;
|
||||||
|
private Boolean active = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of Chat (local)
|
||||||
|
* @parametres
|
||||||
|
* @param remoteUser : remoteUser => référence de l'utilisateur distant
|
||||||
|
* @description
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public Chat(RemoteUser rm) {
|
||||||
|
this.remoteUser=rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** GETTERS ***/
|
||||||
|
public RemoteUser getRemoteUser() {
|
||||||
|
return remoteUser;
|
||||||
|
}
|
||||||
|
public ArrayList<Message> getMessages() {
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
public Socket getUserSocket() {
|
||||||
|
return userSocket;
|
||||||
|
}
|
||||||
|
public Boolean getActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** SETTERS ***/
|
||||||
|
public void setRemoteUser(RemoteUser rm) {
|
||||||
|
this.remoteUser = rm;
|
||||||
|
}
|
||||||
|
public void setSocket(Socket link) {
|
||||||
|
this.userSocket = link;
|
||||||
|
}
|
||||||
|
public void addMessage(Message msg) {
|
||||||
|
this.messages.add(msg);
|
||||||
|
}
|
||||||
|
public void addListMessage( ArrayList<Message> msg) {
|
||||||
|
this.messages=msg;
|
||||||
|
}
|
||||||
|
public void activate() {
|
||||||
|
this.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
this.active = false;
|
||||||
|
try {
|
||||||
|
this.userSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
149
Application/Clavardage/src/model/LocalUser.java
Normal file
149
Application/Clavardage/src/model/LocalUser.java
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
|
public class LocalUser extends User{
|
||||||
|
|
||||||
|
|
||||||
|
/*** ATTRIBUTS ***/
|
||||||
|
private int portUDPsend;
|
||||||
|
private int portUDPlistening;
|
||||||
|
private ArrayList<RemoteUser> remoteUsersList = new ArrayList<RemoteUser>(); // listes des utilisateurs actifs
|
||||||
|
private ArrayList<Chat> chats = new ArrayList<Chat>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of LocalUser
|
||||||
|
* @parametres
|
||||||
|
* @param pseudo : String
|
||||||
|
* @param addIP : InetAddress
|
||||||
|
* @param portUDPsend : int => le numéro de port pour envoyé 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 portTCP : int => le numéro de port pour commencer une nouvelle conversation
|
||||||
|
* @description
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public LocalUser(String pseudo,InetAddress addIP,int portUDPsend,int portUDPlistening,int portTCP){
|
||||||
|
super(pseudo,addIP,portTCP);
|
||||||
|
this.portUDPsend = portUDPsend;
|
||||||
|
this.portUDPlistening = portUDPlistening;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** GETTERS ***/
|
||||||
|
public int getPortUDPsend() {
|
||||||
|
return portUDPsend;
|
||||||
|
}
|
||||||
|
public int getPortUDPlistening() {
|
||||||
|
return portUDPlistening;
|
||||||
|
}
|
||||||
|
public ArrayList<RemoteUser> getRemoteUsersList() {
|
||||||
|
return remoteUsersList;
|
||||||
|
}
|
||||||
|
public ArrayList<Chat> getChats() {
|
||||||
|
return chats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** SETTERS ***/
|
||||||
|
public void setPortUDPsend(int portUDPsend) {
|
||||||
|
this.portUDPsend = portUDPsend;
|
||||||
|
}
|
||||||
|
public void setPortUDPlistening(int portUDPlistening) {
|
||||||
|
this.portUDPlistening = portUDPlistening;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parameters
|
||||||
|
* @param remoteUserIP : InetAddress => l'adresse IP de l'utilisateur distant
|
||||||
|
* @param remoteUserPortTCP : int => le numéro de port TCP d'écoute de l'utilisateur distant
|
||||||
|
* @param remoteUserPseudo : String => le pseudo de l'utilisateur distant
|
||||||
|
* <p>
|
||||||
|
* Ajout ou mise à jour l'utilisateur distant dans notre liste d'utilisateur distant
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void addRemoteUser(InetAddress remoteUserIP, int remoteUserPortTCP,String remoteUserPseudo) {
|
||||||
|
RemoteUser tmpRemoteUser = new RemoteUser(remoteUserPseudo,remoteUserIP,remoteUserPortTCP);
|
||||||
|
int index = this.remoteUsersList.indexOf(tmpRemoteUser);
|
||||||
|
if(index!=-1) {
|
||||||
|
System.out.println("("+this.pseudo+") "+"MAJ, IP(port) : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
|
||||||
|
this.remoteUsersList.get(index).setAddIP(remoteUserIP);
|
||||||
|
this.remoteUsersList.get(index).setPortTCP(remoteUserPortTCP);
|
||||||
|
this.remoteUsersList.get(index).setPseudo(remoteUserPseudo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("("+this.pseudo+") "+"Add new user IP(port) : "+remoteUserPseudo+" => "+remoteUserIP+"("+remoteUserPortTCP+")");
|
||||||
|
this.remoteUsersList.add(tmpRemoteUser);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int i = getChatIndexOf(tmpRemoteUser);
|
||||||
|
if(i!=-1) {
|
||||||
|
chats.get(i).setRemoteUser(tmpRemoteUser);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chat addChats(RemoteUser rm) {
|
||||||
|
Chat newChat= new Chat(rm);
|
||||||
|
|
||||||
|
if(getChatIndexOf(rm)==-1) {
|
||||||
|
this.getChats().add(newChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newChat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getChatIndexOf(RemoteUser rm) {
|
||||||
|
int index=0;
|
||||||
|
|
||||||
|
Boolean found = false;
|
||||||
|
while(index<this.chats.size() && !found) {
|
||||||
|
|
||||||
|
found = (this.chats.get(index).getRemoteUser() == rm);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if(found) {
|
||||||
|
return index-1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActiveUserIndexOf(RemoteUser rm) {
|
||||||
|
int index = 0;
|
||||||
|
Boolean found = false;
|
||||||
|
//System.out.println(rm);
|
||||||
|
while(index<this.remoteUsersList.size() && !found) {
|
||||||
|
found = (this.remoteUsersList.get(index).equals(rm));
|
||||||
|
/*
|
||||||
|
System.out.println(found);
|
||||||
|
System.out.println(this.remoteUsersList.get(index));
|
||||||
|
System.out.println(this.remoteUsersList.get(index).getPortTCP()==rm.getPortTCP());
|
||||||
|
System.out.println(this.remoteUsersList.get(index).getAddIP()==rm.getAddIP());
|
||||||
|
*/
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if(found) {
|
||||||
|
return index-1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeChat(Chat c) {
|
||||||
|
this.chats.get(getChatIndexOf(c.getRemoteUser())).close();
|
||||||
|
this.chats.remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeAllChat() {
|
||||||
|
int length =this.chats.size();
|
||||||
|
for(int i=0;i<length;i++) {
|
||||||
|
this.closeChat(this.chats.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
Application/Clavardage/src/model/Message.java
Normal file
49
Application/Clavardage/src/model/Message.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
public abstract class Message {
|
||||||
|
|
||||||
|
/*** ATTRIBUTS ***/
|
||||||
|
private String date;
|
||||||
|
private User autor;
|
||||||
|
/**
|
||||||
|
* Constructor of Message
|
||||||
|
* @parametres
|
||||||
|
* @param authorIP : InetAddress
|
||||||
|
* @description
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public Message(User autor) {
|
||||||
|
this.autor = autor;
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||||
|
this.date = dateFormat.format(new Date());
|
||||||
|
}
|
||||||
|
public Message(User autor, String date) {
|
||||||
|
this.autor = autor;
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
/*** GETTERS ***/
|
||||||
|
public String getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
public User getAutor() {
|
||||||
|
return autor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** SETTERS ***/
|
||||||
|
public void setAutorIP(User autor) {
|
||||||
|
this.autor = autor;
|
||||||
|
}
|
||||||
|
public void setDate(String date) {
|
||||||
|
this.date=date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract Object getMessage();
|
||||||
|
}
|
26
Application/Clavardage/src/model/Msg_Text.java
Normal file
26
Application/Clavardage/src/model/Msg_Text.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class Msg_Text extends Message{
|
||||||
|
|
||||||
|
/*** ATTRIBUT ***/
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public Msg_Text(User autor,String text) {
|
||||||
|
super(autor);
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
public Msg_Text(User autor,String date, String text) {
|
||||||
|
super(autor,date);
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
18
Application/Clavardage/src/model/RemoteUser.java
Normal file
18
Application/Clavardage/src/model/RemoteUser.java
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class RemoteUser extends User{
|
||||||
|
|
||||||
|
public RemoteUser(String pseudo, InetAddress addIP, int portTCP) {
|
||||||
|
super(pseudo, addIP, portTCP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RemoteUser [pseudo=" + pseudo + ", addIP=" + addIP + ", portTCP=" + portTCP + ", IPcode=" + IPcode
|
||||||
|
+ "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
106
Application/Clavardage/src/model/User.java
Normal file
106
Application/Clavardage/src/model/User.java
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package model;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
|
public abstract class User {
|
||||||
|
|
||||||
|
|
||||||
|
/*** ATTRIBUTS ***/
|
||||||
|
protected String pseudo;
|
||||||
|
protected InetAddress addIP;
|
||||||
|
protected int portTCP;
|
||||||
|
protected int IPcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of User (local)
|
||||||
|
* @parametres
|
||||||
|
* @param pseudo : String
|
||||||
|
* @param addIP : InetAddress
|
||||||
|
* @param portTCP : int => le numéro de port pour commencer une nouvelle conversation
|
||||||
|
* @description
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public User(String pseudo,InetAddress addIP,int portTCP){
|
||||||
|
this.pseudo = pseudo;
|
||||||
|
this.addIP=addIP;
|
||||||
|
this.portTCP=portTCP;
|
||||||
|
this.IPcode=hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** GETTERS ***/
|
||||||
|
public int getIPcode() {
|
||||||
|
return IPcode;
|
||||||
|
}
|
||||||
|
public String getPseudo() {
|
||||||
|
return pseudo;
|
||||||
|
}
|
||||||
|
public InetAddress getAddIP() {
|
||||||
|
return addIP;
|
||||||
|
}
|
||||||
|
public int getPortTCP() {
|
||||||
|
return portTCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** SETTERS ***/
|
||||||
|
public void setPseudo(String pseudo) {
|
||||||
|
this.pseudo = pseudo;
|
||||||
|
}
|
||||||
|
public void setAddIP(InetAddress addIP) {
|
||||||
|
this.addIP = addIP;
|
||||||
|
}
|
||||||
|
public void setPortTCP(int portTCP) {
|
||||||
|
this.portTCP = portTCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
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)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User [pseudo=" + pseudo + ", addIP=" + addIP.getHostAddress() + ", portTCP=" + portTCP + ", IPcode=" + IPcode + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
285
Application/Clavardage/src/view/Interface.java
Normal file
285
Application/Clavardage/src/view/Interface.java
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
package view;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import controller.Controller;
|
||||||
|
|
||||||
|
public class Interface extends JFrame implements ActionListener, WindowListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L; //JFrame stuff
|
||||||
|
|
||||||
|
public Controller controller;
|
||||||
|
|
||||||
|
public JLabel Pseudolabel;
|
||||||
|
public JLabel ChangePseudolabel;
|
||||||
|
public JTextField ChangePseudotextField;
|
||||||
|
|
||||||
|
public JTextArea MessagetextArea;
|
||||||
|
public JTextField MessagetextField;
|
||||||
|
public JScrollPane scrollpane;
|
||||||
|
|
||||||
|
public JButton RemoteUserButton;
|
||||||
|
public JComboBox<String> RemoteUserbox;
|
||||||
|
public JButton CloseConversationButton;
|
||||||
|
|
||||||
|
//Specifies the look and feel to use. Valid values:
|
||||||
|
//null (use the default), "Metal", "System", "Motif", "GTK+"
|
||||||
|
final static String LOOKANDFEEL = "System";
|
||||||
|
|
||||||
|
public Interface(Controller controller) {
|
||||||
|
this.controller = controller;
|
||||||
|
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
this.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(java.awt.event.WindowEvent e) {
|
||||||
|
System.out.println("Window closing");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Component createComponents() {
|
||||||
|
|
||||||
|
//Pseudo setup
|
||||||
|
JPanel changePseudoPanel = new JPanel(new GridLayout(1, 0));
|
||||||
|
ChangePseudolabel = new JLabel("Change nickname : ");
|
||||||
|
changePseudoPanel.add(ChangePseudolabel);
|
||||||
|
ChangePseudotextField = new JTextField();
|
||||||
|
ChangePseudotextField.setColumns(10);
|
||||||
|
ChangePseudotextField.addActionListener(this);
|
||||||
|
changePseudoPanel.add(ChangePseudotextField);
|
||||||
|
|
||||||
|
Pseudolabel = new JLabel("Nickname : "+controller.getMyUser().getPseudo());
|
||||||
|
Pseudolabel.setLabelFor(ChangePseudotextField);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Remote user list setup
|
||||||
|
RemoteUserButton = new JButton("Start session");
|
||||||
|
RemoteUserButton.addActionListener(this);
|
||||||
|
|
||||||
|
|
||||||
|
// Remote user list
|
||||||
|
//Converts the Userlist to a Pseudotab for treatment in actionPerformed
|
||||||
|
String[] pseudotab = controller.askUpdateActiveUsers();
|
||||||
|
RemoteUserbox = new JComboBox<String>(pseudotab);
|
||||||
|
RemoteUserbox.setEditable(true);
|
||||||
|
RemoteUserbox.addActionListener(this);
|
||||||
|
RemoteUserbox.setVisible(false);
|
||||||
|
|
||||||
|
// Close session
|
||||||
|
CloseConversationButton = new JButton("Close session");
|
||||||
|
CloseConversationButton.addActionListener(this);
|
||||||
|
CloseConversationButton.setVisible(false);
|
||||||
|
|
||||||
|
JPanel userListsPanel = new JPanel(new GridLayout(1, 0));
|
||||||
|
|
||||||
|
userListsPanel.add(RemoteUserButton);
|
||||||
|
userListsPanel.add(RemoteUserbox);
|
||||||
|
userListsPanel.add(CloseConversationButton);
|
||||||
|
|
||||||
|
|
||||||
|
//Messages setup
|
||||||
|
MessagetextField = new JTextField();
|
||||||
|
MessagetextField.setColumns(10);
|
||||||
|
MessagetextField.addActionListener(this);
|
||||||
|
MessagetextArea = new JTextArea("Chat");
|
||||||
|
scrollpane = new JScrollPane();
|
||||||
|
scrollpane.getViewport().add(MessagetextArea);
|
||||||
|
scrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||||
|
scrollpane.setPreferredSize(new Dimension(600,60));
|
||||||
|
MessagetextField.setVisible(false);
|
||||||
|
MessagetextArea.setVisible(false);
|
||||||
|
scrollpane.setVisible(false);
|
||||||
|
// Create a placeholder on JTextField
|
||||||
|
MessagetextField.addFocusListener(new FocusListener() {
|
||||||
|
@Override
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
if (MessagetextField.getText().equals("Your message")) {
|
||||||
|
MessagetextField.setText("");
|
||||||
|
MessagetextField.setForeground(Color.BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
if (MessagetextField.getText().isEmpty()) {
|
||||||
|
MessagetextField.setForeground(Color.GRAY);
|
||||||
|
MessagetextField.setText("Your message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An easy way to put space between a top-level container
|
||||||
|
* and its contents is to put the contents in a JPanel
|
||||||
|
* that has an "empty" border.
|
||||||
|
*/
|
||||||
|
JPanel header = new JPanel(new GridLayout(0, 1));
|
||||||
|
header.add(Pseudolabel);
|
||||||
|
header.add(changePseudoPanel);
|
||||||
|
header.add(userListsPanel);
|
||||||
|
|
||||||
|
JPanel pane = new JPanel(new BorderLayout());
|
||||||
|
pane.add(header,BorderLayout.NORTH);
|
||||||
|
pane.add(scrollpane,BorderLayout.CENTER);
|
||||||
|
pane.add(MessagetextField,BorderLayout.SOUTH);
|
||||||
|
pane.setBorder(BorderFactory.createEmptyBorder(
|
||||||
|
30, //top
|
||||||
|
30, //left
|
||||||
|
10, //bottom
|
||||||
|
30) //right
|
||||||
|
);
|
||||||
|
|
||||||
|
return pane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if(e.getSource() == ChangePseudotextField) { //Changing pseudo
|
||||||
|
String Textinput = ChangePseudotextField.getText();
|
||||||
|
Pseudolabel.setText("Your current username is: " + Textinput);
|
||||||
|
|
||||||
|
try {
|
||||||
|
controller.changePseudo();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
System.out.println("Error in change pseudo\n");
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}else if(e.getSource() == MessagetextField){ //Messages
|
||||||
|
String Textinput = MessagetextField.getText();
|
||||||
|
MessagetextArea.setText(MessagetextArea.getText() + "\n" + controller.getMyUser().getPseudo() + " : " + Textinput );
|
||||||
|
MessagetextField.setText("");
|
||||||
|
controller.askToSend(Textinput); // ask to send to controller
|
||||||
|
|
||||||
|
}else if(e.getSource() == RemoteUserButton) { //Shows remote user list
|
||||||
|
RemoteUserbox.setVisible(true);
|
||||||
|
}else if(e.getSource() == CloseConversationButton) {
|
||||||
|
controller.askCloseSession();
|
||||||
|
MessagetextArea.setVisible(false);
|
||||||
|
scrollpane.setVisible(false);
|
||||||
|
MessagetextField.setVisible(false);
|
||||||
|
CloseConversationButton.setVisible(false);
|
||||||
|
}else if(e.getSource() == RemoteUserbox){ // Choice in remote user list
|
||||||
|
|
||||||
|
//JComboBox cb = (JComboBox)e.getSource(); //Casts obscurs pour récupérer le numéro du user dans la liste
|
||||||
|
int selectedUsernb = RemoteUserbox.getSelectedIndex();
|
||||||
|
//String.valueOf(((String) cb.getSelectedItem()).charAt(1)));
|
||||||
|
|
||||||
|
// start or switch chat => get history
|
||||||
|
String history = controller.askOpenSession(selectedUsernb);
|
||||||
|
// display it
|
||||||
|
MessagetextArea.setText(history);
|
||||||
|
MessagetextField.setVisible(true);
|
||||||
|
scrollpane.setVisible(true);
|
||||||
|
MessagetextArea.setVisible(true);
|
||||||
|
CloseConversationButton.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initLookAndFeel() {
|
||||||
|
// Swing allows you to specify which look and feel your program uses-
|
||||||
|
// -Java,
|
||||||
|
// GTK+, Windows, and so on as shown below.
|
||||||
|
String lookAndFeel = null;
|
||||||
|
|
||||||
|
if (LOOKANDFEEL != null) {
|
||||||
|
if (LOOKANDFEEL.equals("Metal")) {
|
||||||
|
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
|
||||||
|
} else if (LOOKANDFEEL.equals("System")) {
|
||||||
|
lookAndFeel = UIManager.getSystemLookAndFeelClassName();
|
||||||
|
} else if (LOOKANDFEEL.equals("Motif")) {
|
||||||
|
lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||||||
|
} else if (LOOKANDFEEL.equals("GTK+")) { //new in 1.4.2
|
||||||
|
lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
|
||||||
|
} else {
|
||||||
|
System.err.println("Unexpected value of LOOKANDFEEL specified: " + LOOKANDFEEL);
|
||||||
|
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
|
||||||
|
}
|
||||||
|
try {UIManager.setLookAndFeel(lookAndFeel);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
System.err.println("Couldn't find class for specified look and feel:" + lookAndFeel);
|
||||||
|
System.err.println("Did you include the L&F library in the class path?");
|
||||||
|
System.err.println("Using the default look and feel.");
|
||||||
|
} catch (UnsupportedLookAndFeelException e) {
|
||||||
|
System.err.println("Can't use the specified look and feel (" + lookAndFeel+ ") on this platform.");
|
||||||
|
System.err.println("Using the default look and feel.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Couldn't get specified look and feel (" + lookAndFeel + "), for some reason.");
|
||||||
|
System.err.println("Using the default look and feel.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the GUI and show it. For thread safety,
|
||||||
|
* this method should be invoked from the
|
||||||
|
* event-dispatching thread.
|
||||||
|
*/
|
||||||
|
public static Interface createAndShowGUI(Controller controller) {
|
||||||
|
//Set the look and feel.
|
||||||
|
initLookAndFeel();
|
||||||
|
|
||||||
|
//Make sure we have nice window decorations.
|
||||||
|
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||||
|
|
||||||
|
//Create and set up the window.
|
||||||
|
JFrame frame = new JFrame("Clavardage App");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
Interface app = new Interface(controller);
|
||||||
|
Component contents = app.createComponents();
|
||||||
|
frame.getContentPane().add(contents, BorderLayout.CENTER);
|
||||||
|
frame.setPreferredSize(new Dimension(400,300));
|
||||||
|
|
||||||
|
//Ends all running background tasks upon closing the window
|
||||||
|
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
|
||||||
|
System.out.println("("+controller.getMyUser().getPseudo()+") Window has been closed");
|
||||||
|
controller.askForClose();
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Display the window.
|
||||||
|
frame.pack();
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void windowOpened(WindowEvent e) {} //Had to implement it for WindowListener
|
||||||
|
public void windowActivated(WindowEvent e) {}
|
||||||
|
public void windowIconified(WindowEvent e) {}
|
||||||
|
public void windowDeiconified(WindowEvent e) {}
|
||||||
|
public void windowDeactivated(WindowEvent e) {}
|
||||||
|
public void windowClosed(WindowEvent e) {}
|
||||||
|
public void windowClosing(WindowEvent e) {}
|
||||||
|
|
||||||
|
|
||||||
|
public void notifyNewMessage(String msg) {
|
||||||
|
MessagetextArea.setText(MessagetextArea.getText() + "\n" + msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateActiveUsers() {
|
||||||
|
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>( controller.askUpdateActiveUsers() );
|
||||||
|
RemoteUserbox.setModel( model );
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
//Schedule a job for the event-dispatching thread:
|
||||||
|
//creating and showing this application’s GUI.
|
||||||
|
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
createAndShowGUI();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
}
|
39
Application/Clavardage/src/websocket/Appel.java
Normal file
39
Application/Clavardage/src/websocket/Appel.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
5
Application/Clavardage/src/websocket/Centralized.java
Normal file
5
Application/Clavardage/src/websocket/Centralized.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package websocket;
|
||||||
|
|
||||||
|
public class Centralized {
|
||||||
|
|
||||||
|
}
|
26
Application/Clavardage/src/websocket/Client.java
Normal file
26
Application/Clavardage/src/websocket/Client.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Tomcat WebSocket</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<form>
|
|
||||||
<input id="pseudo" type="text">
|
|
||||||
<input id="message_id" type="text">
|
|
||||||
<input id="message" type="text">
|
|
||||||
<input onclick="wsSetPseudo(pseudo);" value="Set_Pseudo" type="button">
|
|
||||||
<input onclick="wsSendMessage();" value="Send" type="button">
|
|
||||||
<input onclick="wsCloseConnection();" value="Disconnect" type="button">
|
|
||||||
<input onclick="wsSendId(message_id);" value="Choose_addressee" type="button">
|
|
||||||
</form>
|
|
||||||
<br>
|
|
||||||
<textarea id="echoText" rows="5" cols="30"></textarea>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var webSocket = new WebSocket("ws://localhost:8082/WebSocketServer/websocketendpoint");
|
|
||||||
var echoText = document.getElementById("echoText");
|
|
||||||
echoText.value = "";
|
|
||||||
var message = document.getElementById("message");
|
|
||||||
var message_id = document.getElementById("message_id");
|
|
||||||
var pseudo= document.getElementById("pseudo");
|
|
||||||
webSocket.onopen = function(message){ wsOpen(message);};
|
|
||||||
webSocket.onmessage = function(message){ wsGetMessage(message);};
|
|
||||||
webSocket.onclose = function(message){ wsClose(message);};
|
|
||||||
webSocket.onerror = function(message){ wsError(message);};
|
|
||||||
function wsSetPseudo(pseudo){
|
|
||||||
echoText.value += "Changing Pseudo... \n";
|
|
||||||
websocket.send("P "+pseudo);
|
|
||||||
pseudo.value="";
|
|
||||||
}
|
|
||||||
function wsSendId(message_id){
|
|
||||||
echoText.value += "Sending addressee Id... \n";
|
|
||||||
webSocket.send(message_id.value);
|
|
||||||
message_id.value="";
|
|
||||||
}
|
|
||||||
function wsOpen(message){
|
|
||||||
echoText.value += "Connected ... \n";
|
|
||||||
websocket.send ("I "+getRandomInt(10000));
|
|
||||||
}
|
|
||||||
|
|
||||||
function wsSendMessage(){
|
|
||||||
webSocket.send(message.value);
|
|
||||||
echoText.value += "Message sended to the server : " + message.value + "\n";
|
|
||||||
message.value = "";
|
|
||||||
}
|
|
||||||
function wsCloseConnection(){
|
|
||||||
webSocket.close();
|
|
||||||
}
|
|
||||||
function wsGetMessage(message){
|
|
||||||
echoText.value += "Message received from to the server : " + message.data + "\n";
|
|
||||||
}
|
|
||||||
function wsClose(message){
|
|
||||||
echoText.value += "Disconnect ... \n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function wsError(message){
|
|
||||||
echoText.value += "Error ... \n";
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,7 +0,0 @@
|
||||||
package server.ws;
|
|
||||||
|
|
||||||
public class Chat {
|
|
||||||
private MatchingId User1;
|
|
||||||
private MatchingId User2;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package server.ws;
|
|
||||||
|
|
||||||
public class MatchingId {
|
|
||||||
|
|
||||||
private Integer Id;
|
|
||||||
private String Pseudo;
|
|
||||||
private int UDPport ;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package server.ws;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import javax.websocket.OnClose;
|
|
||||||
import javax.websocket.OnError;
|
|
||||||
import javax.websocket.OnMessage;
|
|
||||||
import javax.websocket.OnOpen;
|
|
||||||
import javax.websocket.server.ServerEndpoint;
|
|
||||||
|
|
||||||
@ServerEndpoint("/websocketendpoint")
|
|
||||||
public class Server {
|
|
||||||
|
|
||||||
private ArrayList<Chat> connexions_chat=new ArrayList<Chat>();
|
|
||||||
private ArrayList<MatchingId> annuaire_extern_users=new ArrayList<MatchingId>();
|
|
||||||
private ArrayList<MatchingId> annuaire_intern_users=new ArrayList<MatchingId>();
|
|
||||||
|
|
||||||
|
|
||||||
public boolean estUnEntier(String chaine) {
|
|
||||||
try {
|
|
||||||
Integer.parseInt(chaine);
|
|
||||||
} catch (NumberFormatException e){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnOpen
|
|
||||||
public void onOpen(){
|
|
||||||
System.out.println("Open Connection ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClose
|
|
||||||
public void onClose(){
|
|
||||||
System.out.println("Close Connection ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnMessage
|
|
||||||
public void onMessage(String message){
|
|
||||||
String chara=message.substring(0);
|
|
||||||
if(chara=="I" ) {
|
|
||||||
//insertion tab matchinid;
|
|
||||||
//-----> BROADCAST
|
|
||||||
}
|
|
||||||
else if (chara=="P"){
|
|
||||||
//insertion tab;
|
|
||||||
}
|
|
||||||
else if(estUnEntier(message)) {
|
|
||||||
String msg="Le Client correspond avec le destinataire numéro: "+message;
|
|
||||||
System.out.println(msg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.println("Message from the client: " + message);
|
|
||||||
}
|
|
||||||
//String echoMsg = "Echo from the server : " + message;
|
|
||||||
//return echoMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnError
|
|
||||||
public void onError(Throwable e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
BIN
Class_Diagramme.png
Normal file
BIN
Class_Diagramme.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
BIN
Executable/Alexandre_31023.jar
Normal file
BIN
Executable/Alexandre_31023.jar
Normal file
Binary file not shown.
BIN
Executable/Client_31024.jar
Normal file
BIN
Executable/Client_31024.jar
Normal file
Binary file not shown.
BIN
Executable/Leonie_31022.jar
Normal file
BIN
Executable/Leonie_31022.jar
Normal file
Binary file not shown.
BIN
Executable/Theau_31021.jar
Normal file
BIN
Executable/Theau_31021.jar
Normal file
Binary file not shown.
BIN
Final_Composite_Structure_Diagram.jpg
Normal file
BIN
Final_Composite_Structure_Diagram.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
Final_Sequence_Diagram.png
Normal file
BIN
Final_Sequence_Diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 213 KiB |
BIN
Final_State_Machine_Diagram.jpg
Normal file
BIN
Final_State_Machine_Diagram.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
52
README.md
Normal file
52
README.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
COO/POO 2020
|
||||||
|
SYSTEME DE CLAVARDAGE DISTRIBUE INTERACTIF MULTI-UTILISATEUR TEMPS REEL
|
||||||
|
|
||||||
|
4IR A2
|
||||||
|
Alexandre Gonzalvez
|
||||||
|
Théau Giraud
|
||||||
|
Léonie Gallois
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*************Manuel d’installation & d’utilisation de l’application*************
|
||||||
|
|
||||||
|
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 d’abord, allez sur le GitEtud de L’INSA Toulouse à cette adresse: https://git.etud.insa-toulouse.fr/gallois/Clavardage. Notre projet s’appelle Clavardage, vous pouvez effectuer un pull à partir de la branche master. (D’autres 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 l’historique).
|
||||||
|
|
||||||
|
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 n’est 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 n’y 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 l’application et du côté du serveur.
|
||||||
|
|
||||||
|
Etape 3: Connexion au VPN de L’INSA
|
||||||
|
|
||||||
|
Si vous utilisez une machine se situant à l’INSA vous pouvez passer cette étape. Sinon, il vous faudra vous connecter au réseau de l’INSA 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 l’application
|
||||||
|
|
||||||
|
Vérifiez bien d’être connecté au VPN avant de tester l’application. 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 qu’un ou plusieurs des .jar utilisateurs distants.
|
||||||
|
|
||||||
|
Quand vous ouvrez l’application, une fenêtre apparaît vous demandant votre Pseudo. Vous recevrez un message de confirmation avec votre Pseudo affiché ou un message d’erreur s’il n’est pas valide.
|
||||||
|
|
||||||
|
L’interface s’ouvrira ensuite. Vous pourrez changer votre Pseudo dans la barre de texte à côté de “Change nickname:”. Les mêmes messages de confirmation/d’erreur 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 s’ouvrira.
|
||||||
|
|
||||||
|
Une fenêtre de chat vide s’ouvre. Vous pouvez y taper vos messages et les envoyer.
|
||||||
|
|
||||||
|
Pour visualiser l’arrivée des messages, établissez la connexion en faisant la même manip sur l’interface de l’utilisateur distant avec lequel vous communiquez. Vous verrez ici qu’un chat existant déjà, une fenêtre s’ouvre en disant que l’on 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 l’utilisateur 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 l’application, vous pouvez (notamment avec un pseudo différent si cela vous chante, votre adresse sera quand même reconnue) relancer un chat avec l’utilisateur 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 d’installation & d’utilisation de l’application*************
|
BIN
Rapport COO.pdf
Normal file
BIN
Rapport COO.pdf
Normal file
Binary file not shown.
BIN
Rapport POO.pdf
Normal file
BIN
Rapport POO.pdf
Normal file
Binary file not shown.
34
Server.java
Normal file
34
Server.java
Normal 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);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
UseCase_Diagram.jpg
Normal file
BIN
UseCase_Diagram.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 MiB |
BIN
boite_noire.pdf
Normal file
BIN
boite_noire.pdf
Normal file
Binary file not shown.
BIN
démonstration_projet_clavardage.mkv
Normal file
BIN
démonstration_projet_clavardage.mkv
Normal file
Binary file not shown.
Loading…
Reference in a new issue