Compare commits

..

2 commits

Author SHA1 Message Date
Cavailles Kevin
1e3a1b4f37 session fonctionnelle, messages simples 2020-12-07 10:41:05 +01:00
Cavailles Kevin
26bdd96bfd debut session 2020-12-04 23:11:39 +01:00
33 changed files with 700 additions and 18 deletions

View file

@ -0,0 +1,61 @@
package communication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import main.Observer;
import main.VueSession;
import messages.MessageTexte;
import messages.MauvaisTypeMessageException;
import messages.Message;
import messages.Message.TypeMessage;
public class TCPClient {
private Socket sockTCP;
private ObjectOutputStream output;
private TCPInputThread inputThread;
public TCPClient(Socket sockTCP) throws IOException {
this.sockTCP = sockTCP;
this.output = new ObjectOutputStream(this.sockTCP.getOutputStream()) ;
ObjectInputStream input = new ObjectInputStream(this.sockTCP.getInputStream());
this.inputThread = new TCPInputThread(input);
}
public TCPClient(InetAddress addr, int port) throws IOException {
this(new Socket(addr, port)) ;
}
public void connexionAccepted() throws IOException {
System.out.println("avant vue");
new VueSession("Application", this);
}
public void startInputThread() {
this.inputThread.start();
}
public void sendMessage(String contenu) throws IOException, MauvaisTypeMessageException {
System.out.println("dans write");
MessageTexte message = new MessageTexte(TypeMessage.TEXTE, contenu);
this.output.writeObject(message);
}
public void setObserverInputThread(Observer o) {
this.inputThread.setObserver(o);
}
}

View file

@ -0,0 +1,34 @@
package communication;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class TCPHandlerConnection extends Thread {
private Socket sockAccept;
public TCPHandlerConnection(Socket sockAccept) {
this.sockAccept = sockAccept;
}
public TCPHandlerConnection(InetAddress addr, int port) throws IOException {
this(new Socket(addr, port));
}
@Override
public void run() {
TCPClient tcpC;
try {
tcpC = new TCPClient(sockAccept);
tcpC.connexionAccepted();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,59 @@
package communication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Arrays;
import main.Observer;
import messages.Message;
public class TCPInputThread extends Thread {
private ObjectInputStream input;
private boolean running;
private char[] buffer;
private Observer obs;
public TCPInputThread(ObjectInputStream input) {
this.input = input;
this.running = true;
this.buffer = new char[200];
}
@Override
public void run() {
while (this.running) {
try {
System.out.println("dans read");
Object o = this.input.readObject();
this.obs.update(this, o);
//this.flushBuffer();
} catch (IOException | ClassNotFoundException e) {
this.interrupt();
e.printStackTrace();
}
}
}
@Override
public void interrupt() {
this.running = false;
}
private void flushBuffer() {
Arrays.fill(this.buffer, '\u0000');
}
protected void setObserver(Observer o) {
this.obs = o;
}
}

View file

@ -0,0 +1,32 @@
package communication;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPServer extends Thread {
private ServerSocket sockListenTCP;
public TCPServer(int port) throws UnknownHostException, IOException {
this.sockListenTCP = new ServerSocket(port, 5, InetAddress.getLocalHost());
}
@Override
public void run() {
Socket sockAccept;
while(true) {
try {
sockAccept = this.sockListenTCP.accept();
new TCPHandlerConnection(sockAccept).run();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

View file

@ -0,0 +1,81 @@
package main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.swing.JButton;
import javax.swing.JList;
import java.util.concurrent.*;
import communication.TCPClient;
import messages.MauvaisTypeMessageException;
import messages.Message;
import messages.MessageTexte;
public class ControleurSession implements ActionListener, Observer {
private VueSession vue;
private TCPClient tcpClient;
protected ControleurSession(VueSession vue, TCPClient tcpClient) throws IOException {
this.vue = vue;
this.tcpClient = tcpClient;
this.tcpClient.setObserverInputThread(this);
this.tcpClient.startInputThread();
}
// ---------- ACTION LISTENER OPERATIONS ----------//
@Override
public void actionPerformed(ActionEvent e) {
//Quand le bouton envoyer est presse
if ((JButton) e.getSource() == this.vue.getButtonEnvoyer()) {
String messageOut = this.vue.getZoneSaisie().getText();
System.out.println(messageOut);
//Si le texte field n'est pas vide
if (!messageOut.equals("")) {
//On recupere la date et on prepare les messages a afficher/envoyer
String date = this.getDateAndTime();
String messageToDisplay = date+" Moi : "+ messageOut;
messageOut = date +" "+ Utilisateur.getSelf().getPseudo() + " : " + messageOut+"\n";
try {
this.tcpClient.sendMessage(messageOut);
} catch (MauvaisTypeMessageException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.vue.appendMessage(messageToDisplay + "\n");
this.vue.resetZoneSaisie();
}
}
}
//Methode appelee quand l'inputStream de la socket de communication recoit des donnees
@Override
public void update(Object o, Object arg) {
MessageTexte messageIn = (MessageTexte) arg;
System.out.println(messageIn.getContenu());
this.vue.appendMessage(messageIn.getContenu());
}
private String getDateAndTime() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
return "<"+dtf.format(now)+">";
}
}

61
POO/src/main/Main.java Normal file
View file

@ -0,0 +1,61 @@
package main;
import java.io.IOException;
import java.net.InetAddress;
import communication.TCPClient;
import communication.TCPServer;
public class Main {
private static int portServers[] = {1526,1501,1551,1561};
private static String ids[] = {"Raijila", "titi33", "Semtexx", "Salam"};
private static String pseudo[] = {"Raijila", "Mirasio", "Semtexx", "Xaegon"};
public static void main(String[] args) {
switch(args[0]) {
case "0":
Main.createApp(0);
break;
case "1":
Main.createApp(1);
break;
case "2":
Main.createApp(2);
break;
default:
Main.createApp(3);
}
// VueStandard.userList.addElement("Mirasio");
//
// try {
// Thread.sleep(2000);
// VueStandard.userList.addElement("Semtexx");
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
private static void createApp(int i) {
try {
Utilisateur.setSelf(Main.ids[i], Main.pseudo[i], "localhost");
System.out.println("Avant tcpcli");
TCPClient tcpCli = new TCPClient(InetAddress.getLocalHost(), 7001);
tcpCli.connexionAccepted();
//new VueSession("Application");
} catch (IOException e) {
System.out.println(e.toString());
}
}
}

View file

@ -0,0 +1,18 @@
package main;
import java.io.IOException;
import communication.TCPServer;
public class MainServTCP {
public static void main(String[] args) {
try {
Utilisateur.setSelf("id1", "toto", "localhost");
new TCPServer(7001).run();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,6 @@
package main;
public interface Observer {
public void update(Object o, Object arg);
}

View file

@ -0,0 +1,51 @@
package main;
import java.io.Serializable;
import java.net.*;
public class Utilisateur implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String pseudo;
private InetAddress ip;
private static Utilisateur self;
public Utilisateur(String id, String pseudo, InetAddress ip) throws UnknownHostException {
this.id = id;
this.pseudo = pseudo;
this.ip = ip;
System.out.println(InetAddress.getLocalHost());
}
public String getId() {
return id;
}
public String getPseudo() {
return pseudo;
}
public void setPseudo(String pseudo) {
this.pseudo = pseudo;
}
public InetAddress getIp() {
return ip;
}
public static void setSelf(String id, String pseudo,String host) throws UnknownHostException {
if(Utilisateur.self == null) {
Utilisateur.self = new Utilisateur(id, pseudo, InetAddress.getByName(host));
}
}
public static Utilisateur getSelf() {
return Utilisateur.self;
}
}

15
POO/src/main/Vue.java Normal file
View file

@ -0,0 +1,15 @@
package main;
import javax.swing.JFrame;
public class Vue extends JFrame{
public Vue(String title) {
super(title);
}
public void reduireAgent() {}
public void fermerAgent() {}
}

View file

@ -0,0 +1,105 @@
package main;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import communication.TCPClient;
public class VueSession extends Vue {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton envoyerMessage;
private JTextArea chatWindow;
private JTextField chatInput;
private ControleurSession c;
public VueSession(String title, TCPClient tcpClient) throws IOException {
super(title);
this.c = new ControleurSession(this, tcpClient);
this.setBounds(100, 100, 600, 600);
JPanel main = new JPanel();
main.setBorder(new EmptyBorder(5, 5, 5, 5));
this.add(main);
main.setLayout(new BorderLayout(0, 0));
JPanel bottom = new JPanel();
main.add(bottom, BorderLayout.SOUTH);
bottom.setLayout(new BorderLayout(0, 0));
this.chatInput = new JTextField();
//textField.setPreferredSize(new Dimension(300, 50));
bottom.add(this.chatInput);
this.chatInput.setColumns(10);
this.envoyerMessage = new JButton("Envoyer");
this.envoyerMessage.addActionListener(this.c);
bottom.add(this.envoyerMessage, BorderLayout.EAST);
this.chatWindow = new JTextArea();
this.chatWindow.setEditable(false);
ScrollPane chatScroll = new ScrollPane();
chatScroll.add(this.chatWindow);
main.add(chatScroll, BorderLayout.CENTER);
this.getRootPane().setDefaultButton(this.envoyerMessage);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(600,600);
this.setVisible(true);
}
protected JButton getButtonEnvoyer() {
return this.envoyerMessage;
}
protected JTextField getZoneSaisie() {
return this.chatInput;
}
protected void resetZoneSaisie() {
this.chatInput.setText("");
}
protected void appendMessage(String message) {
this.chatWindow.append(message);
}
}

View file

@ -0,0 +1,8 @@
package messages;
public class MauvaisTypeMessageException extends Exception {
private static final long serialVersionUID = 1L;
}

View file

@ -0,0 +1,69 @@
package messages;
import java.io.Serializable;
import java.lang.instrument.Instrumentation;
import java.util.Arrays;
import messages.Message.TypeMessage;
public abstract class Message implements Serializable {
public enum TypeMessage {JE_SUIS_CONNECTE, JE_SUIS_DECONNECTE, INFO_PSEUDO, TEXTE, IMAGE, FICHIER, MESSAGE_NUL}
protected TypeMessage type;
private static final long serialVersionUID = 1L;
private static Instrumentation inst;
public TypeMessage getTypeMessage() {
return this.type;
}
protected abstract String attributsToString();
public String toString() {
return this.type+"###"+this.attributsToString();
}
public static Message stringToMessage(String messageString) {
try {
String[] parts = messageString.split("###");
switch (parts[0]) {
case "JE_SUIS_CONNECTE" :
return new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE);
case "JE_SUIS_DECONNECTE" :
return new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE);
case "INFO_PSEUDO" :
return new MessageSysteme(TypeMessage.INFO_PSEUDO, parts[1], parts[2]);
case "TEXTE" :
return new MessageTexte(TypeMessage.TEXTE, parts[1]);
case "IMAGE" :
return new MessageFichier(TypeMessage.IMAGE, parts[1], parts[2]);
case "FICHIER" :
return new MessageFichier(TypeMessage.FICHIER, parts[1], parts[2]);
}
} catch (MauvaisTypeMessageException e) {}
return null;
}
//tests ici
public static void main(String[] args) throws MauvaisTypeMessageException {
Message m1 = new MessageSysteme(TypeMessage.JE_SUIS_CONNECTE);
Message m2 = new MessageSysteme(TypeMessage.JE_SUIS_DECONNECTE);
Message m3 = new MessageSysteme(TypeMessage.INFO_PSEUDO, "pseudo156434518", "id236");
Message m4 = new MessageTexte(TypeMessage.TEXTE, "blablabla");
Message m5 = new MessageFichier(TypeMessage.FICHIER, "truc", ".pdf");
System.out.println(Message.stringToMessage(m1.toString()));
System.out.println(Message.stringToMessage(m2.toString()));
System.out.println(Message.stringToMessage(m3.toString()));
System.out.println(Message.stringToMessage(m4.toString()));
System.out.println(Message.stringToMessage(m5.toString()));
}
}

View file

@ -0,0 +1,33 @@
package messages;
import messages.Message.TypeMessage;
public class MessageFichier extends Message {
private static final long serialVersionUID = 1L;
private String contenu;
private String extension;
public MessageFichier(TypeMessage type, String contenu, String extension) throws MauvaisTypeMessageException{
if ((type==TypeMessage.IMAGE)||(type==TypeMessage.FICHIER)) {
this.type=type;
this.contenu=contenu;
this.extension=extension;
}
else throw new MauvaisTypeMessageException();
}
public String getContenu() {
return this.contenu;
}
public String getExtension() {
return this.extension;
}
@Override
protected String attributsToString() {
return this.contenu+"###"+this.extension;
}
}

View file

@ -0,0 +1,39 @@
package messages;
public class MessageSysteme extends Message {
private static final long serialVersionUID = 1L;
private String pseudo;
private String id;
public MessageSysteme(TypeMessage type) throws MauvaisTypeMessageException{
if ((type==TypeMessage.JE_SUIS_CONNECTE)||(type==TypeMessage.JE_SUIS_DECONNECTE)||(type==TypeMessage.MESSAGE_NUL)) {
this.type=type;
this.pseudo="";
this.id="";
}
else throw new MauvaisTypeMessageException();
}
public MessageSysteme(TypeMessage type, String pseudo, String id) throws MauvaisTypeMessageException {
if (type==TypeMessage.INFO_PSEUDO) {
this.type=type;
this.pseudo=pseudo;
this.id=id;
}
else throw new MauvaisTypeMessageException();
}
public String getPseudo() {
return this.pseudo;
}
public String getId() {
return this.id;
}
@Override
protected String attributsToString() {
return this.pseudo+"###"+this.id;
}
}

View file

@ -0,0 +1,27 @@
package messages;
import messages.Message.TypeMessage;
public class MessageTexte extends Message {
private static final long serialVersionUID = 1L;
private String contenu;
public MessageTexte(TypeMessage type, String contenu) throws MauvaisTypeMessageException{
if (type==TypeMessage.TEXTE) {
this.type=type;
this.contenu=contenu;
}
else throw new MauvaisTypeMessageException();
}
public String getContenu() {
return this.contenu;
}
@Override
protected String attributsToString() {
return this.contenu;
}
}

View file

@ -1,20 +1,3 @@
# Projet_COO_POO # Projet_COO_POO
Projet de 4ème année : Conception et programmation orientée objet d'un systeme de clavardage distribué interactif multi-utilisateur temps réel Projet de 4ème année : Conception et programmation orientée objet d'un systeme de clavardage distribué interactif multi-utilisateur temps réel
Contenu (branche master):
Dossier rapports : rapports de conception et de projet
Dossier application : archives .jar permettant d'exécuter l'application (version classique)
Dossier serveur_presence : archives .jar et .war permettant d'exécuter respectivement l'application (version compatible avec le serveur) et le serveur de présence
Pour récupérer les codes sources :
- De l'application classique : branche application
- Du serveur et de l'application modifiée : branche serveur_presence (l'application est dans le projet POO, le servlet dans le projet POO_Server)
Toutes les autres branches concernent des versions obsolètes de l'application, merci de ne pas en tenir compte.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

0
modelisation/dossmod.txt Normal file
View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.