Département R & T - S4 - Module M4207 [email protected] TP 2 : Application SnapTchat 20 février 2015 SnapTchat : cahier de charges L’objectif de ce TP est de développer une simple application d’échange de messages courts entre deux utilisateurs. Le cahier des charges de l’application souhaitée stipule les besoins suivants : 1. L’application permet l’échange de messages entre deux utilisateurs. 2. L’application offre une interface graphique pour la saisi des messages à envoyer et pour l’affiche des messages reçus et envoyés. 3. L’échange de message s’appuie sur le protocole UDP. 4. Chaque message affiché s’efface automatiquement au bout d’un temps court (ex. 10 secondes). Travail demandé 1. Proposer une architecture logicielle générique de l’application Snapchat. 2. Fournie une implémentation en Java de l’architecture proposée. 3. Proposer une extension de l’application afin de supporter l’échange de messages entre un groupes d’utilisateurs. Corrigé interface ClientServeur import java.io.*; public interface ClientServeur { /** on sait à qui on parle : adresse IP (ou nom de machine) et port distants sont connus **/ public void envoyerMessage(String message) throws IOException; public String recevoirMessage() throws IOException; } 1 Département R & T - S4 - Module M4207 [email protected] class ClientServeurUDP import java.net.*; import java.io.*; public abstract class ClientServeurUDP implements ClientServeur { protected DatagramSocket socket; protected InetAddress adresseIPDistante; protected int portDistant; public void envoyerMessage(String message) throws IOException {// construction du paquet surdimensionné DatagramPacket packet = new DatagramPacket(message.getBytes(),message.length socket.send(packet); } // méthode recevoirMessage du serveur public String recevoirMessage()throws IOException { byte buffer[]=new byte[16000]; DatagramPacket packet = new DatagramPacket(buffer,buffer.length);// préparat socket.receive(packet); this.portDistant=packet.getPort(); this.adresseIPDistante=packet.getAddress(); return(new String(packet.getData()).trim()); } }//fin de la classe ClientServeurUDP class TableTemp import java.util.*; public class TableTemp extends Observable { private static int mid; /* messge id*/ private Hashtable<Integer,String> tab_m; // table des messges private Hashtable<Integer,STTimer> tab_t; // table de temporisateurs private int timeout; /* duree du temporisateurs */ public TableTemp(int timeout) throws Exception { if (timeout > 1000){ // au moins une second 2 Département R & T - S4 - Module M4207 [email protected] this.timeout=timeout; this.tab_m = new Hashtable<Integer,String>(); this.tab_t= new Hashtable<Integer,STTimer>(); } } public synchronized String getText(){ // retourner un String formatté content les messges dans tab_m String msg = new String(); for (Enumeration e=this.tab_m.keys() ; e.hasMoreElements();){ msg=msg+this.tab_m.get(e.nextElement())+"\n"; } System.out.println("getText : "+msg); return msg; } public synchronized void addMessge(String m){ this.mid++; this.tab_m.put(this.mid,m); this.tab_t.put(this.mid,new STTimer(this.timeout,this.mid,this)); this.tab_t.get(this.mid).start(); this.setChanged(); // marquer le changement this.notifyObservers(this.getText()); } public synchronized void removeMessge(int mid) throws Exception { this.tab_m.remove(mid); this.setChanged(); // marquer le changement this.notifyObservers(this.getText()); } } class STTimer import java.util.*; class STTimer extends Thread { private TableTemp tab; private int timeOut; private int mid; // messge id 3 Département R & T - S4 - Module M4207 [email protected] public STTimer(int timeout,int mid,TableTemp tab){ this.tab= tab; this.timeOut=timeout; this.mid=mid; } public void run(){ try{ this.sleep(this.timeOut); this.tab.removeMessge(mid); }catch (Exception e){} } } class NetHandler import java.io.*; import java.net.*; public class NetHandler extends ClientServeurUDP implements Runnable { private TableTemp tab; public NetHandler(DatagramSocket soc, TableTemp tab){ this.tab=tab; this.socket=soc; } public void run(){ while(true){ try{ String str=this.recevoirMessage(); this.tab.addMessge(str); System.out.println(str); }catch (Exception e){} } } } 4 Département R & T - S4 - Module M4207 [email protected] class STGui import java.awt.*; import javax.swing.*; public class STGui extends JPanel { protected JTextField input; protected JTextArea display; protected JButton send; public STGui() { JPanel up,down; up = new JPanel(); down= new JPanel(); this.setLayout(new BorderLayout()); this.input = new JTextField(40); this.send = new JButton("send"); this.display= new JTextArea(); up.add(this.display); down.add(this.input); down.add(this.send); this.add(up,BorderLayout.NORTH); this.add(down,BorderLayout.SOUTH); } public JButton getSendButton(){ return this.send; } public JTextArea getDispaly(){ return this.display; } public String getText(){ return this.input.getText(); } public void clearTextField(){ 5 Département R & T - S4 - Module M4207 [email protected] this.input.setText(""); } public void displayMessge(String str){ this.display.setText(str); } } class SnapTcaht import import import import import java.util.*; java.net.*; java.awt.*; javax.swing.*; java.awt.event.*; public class SnapTchat extends ClientServeurUDP implements ActionListener, Observer { protected NetHandler netHandler; protected TableTemp tab; protected STGui gui; private int localPort; public SnapTchat(int lport,InetAddress distAdr, int dport) throws Exception{ if ((lport > 1024) && (dport>1024) && distAdr !=null){ this.localPort= lport; this.socket = new DatagramSocket(lport); this.adresseIPDistante=distAdr; this.portDistant=dport; this.tab= new TableTemp(5000); this.gui= new STGui(); this.gui.getSendButton().addActionListener(this); this.netHandler = new NetHandler(this.socket,this.tab); this.tab.addObserver(this); new Thread(this.netHandler).start(); }else{ throw new Exception(); } } public JPanel getGui(){ return this.gui; 6 Département R & T - S4 - Module M4207 [email protected] } public void actionPerformed(ActionEvent e){ // activation du button send String str = this.gui.getText(); this.tab.addMessge(str); try{ this.envoyerMessage(str); this.gui.clearTextField(); }catch (Exception ex){} } public void update(Observable obj, Object arg){ if (obj==this.tab){ String str= (String) arg; this.gui.displayMessge(str); } } public static void main (String[] args){ SnapTchat s; JFrame win; try{ s= new SnapTchat(Integer.parseInt(args[0]), InetAddress.getByName(args[1]), Integer.parseInt(args[2])); win = new JFrame("Snap Tchat"); win.setContentPane(s.getGui()); win.setVisible(true); }catch (Exception e){} } } 7