All pastes #31992 Raw Edit

Anonymous

public text v1 · immutable
#31992 ·published 2005-12-01 17:49 UTC
rendered paste body
//import java.util.Date;
import java.io.*;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;

public class ClientRMIVC extends UnicastRemoteObject implements ClientInterfaceVC, Runnable {

    private volatile Thread clientThread = null;
    static final long serialVersionUID = 42L;
    private String local_name;
    private Random rand = new Random();
    private Tableau local_tableau = new Tableau();
    private Vector clients = new Vector();
    private HashMap vc = new HashMap(); // vecteur horloge
    private MyQueue q = new MyQueue(); // queue des message en attente de livraison (affichage)

    private ClientRMIVC(String name) throws RemoteException {
        super();
        local_name = name;
        vc.put(local_name, new Integer(0));
    }

    public synchronized void register(ClientInterfaceVC client) throws RemoteException {
        if (!(clients.contains(client))) {
            clients.addElement(client);
            vc.put(client.getName(), new Integer(0));
            System.out.println("Nouveau client " + client.getName());
        }
    }

    public synchronized void unregister(ClientInterfaceVC client) throws RemoteException {
        if (clients.removeElement(client)) {
            vc.remove(client.getName());
            System.out.println("Client a quitte");
        } else {
            System.out.println("Client n'etais pas enregistre");
        }
    }

    public String getName() throws RemoteException
    {
        return local_name;
    }

    public static String getInputLine() {
        InputStreamReader isr;
        BufferedReader stdin;
        isr = new InputStreamReader(System.in);
        stdin = new BufferedReader(isr);
        String input = new String();
        try {
            input = stdin.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return input;
    }

    private void printHeader()
    {
        System.out.println("Tableau");
        System.out.println("------------------------------------------------");
    }

    private void broadcastMsg(String strmsg) throws RemoteException, InterruptedException
    {

        // on increment de 1
        vc.put(local_name, new Integer(((Integer)vc.get(local_name)).intValue() + 1));
        Msg msg = new Msg(strmsg, local_name, new HashMap(vc));

        // on l'affiche locallement
        deliverMsg(msg);

        // on transmet aux autres
        for (Enumeration e = clients.elements() ; e.hasMoreElements() ;) 
        {
            ClientInterfaceVC client = (ClientInterfaceVC) e.nextElement();
            try {
                Thread.sleep((long)Math.abs(rand.nextInt(2000)));
                // on envoi le message
                client.addMsg(msg);
            }
            catch (RemoteException ex) {
                System.out.println("Client a quitte");
                unregister(client);
            }
        }
    }

    public void addMsg(Msg msg) throws RemoteException
    {
        System.out.println("Got message");
        q.addQ(msg);
    }

    public void deliveryThread() throws InterruptedException
    {
        while(true)
        {
            for(int i=0; i < q.size(); i++)
            {
                Msg msg;
                HashMap vcm;
                String source;
                boolean good = true;
                msg = q.peek();
                vcm = msg.getVC();
                source = msg.getSource();

                Iterator iter = vcm.keySet().iterator();
                while (iter.hasNext()) {
                    String cur = (String)iter.next();
                    if (cur != source)
                        if (((Integer)vcm.get(cur)).intValue() > 
                                ((Integer)vc.get(cur)).intValue())
                            good = false;
                }
                if (good == true && 
                        ((Integer)vcm.get(source)).intValue() == 
                        ((Integer)vc.get(source)).intValue() + 1)
                {
                    // c'est bon on affiche le message
                    deliverMsg(q.removeQ());
                    vc.put(source, new Integer(((Integer)vc.get(source)).intValue() + 1));
                    break;
                }
                else
                {
                    // on remet le message a la queue de la queue
                    msg = q.removeQ();
                    q.addQ(msg);
                    System.out.println("mise en attente du message " + msg.getMsg() + " par " + msg.getSource());
                }
            }
            Thread.sleep(50);
        }
    }

    public void deliverMsg(Msg msg)
    {
        String strmsg = new String(msg.getSource() + " : " + msg.getMsg());
        local_tableau.addMsg(strmsg);
        printHeader();
        local_tableau.print();
    }

    public void start() {
      if (clientThread == null) {
         clientThread = new Thread(this, "Client");
         clientThread.start();
      }
    }

    public void run()
    {
        // on demarre le reordonnanceur de queue
        new Thread(){ 
            public void run() { 
                try { 
                    ClientRMIVC.this.deliveryThread();
                }
                catch (InterruptedException ex) {
                    System.out.println("Problem with release thread");
                }
            }
        }.start();

        while (true)
        {
            //Date now;
            // on attend de recevoir un message a l'entree
            final String msg = getInputLine();

            // on affiche le nouveau message sur le tableau
            System.out.println("Creating broadcast thread");
            new Thread(){ 
                public void run() { 
                    try { 
                        ClientRMIVC.this.broadcastMsg(msg);
                    }
                    catch (InterruptedException ex) {
                        System.out.println("Problem broadcasting");
                    }
                    catch (RemoteException ex) { 
                        System.out.println("Problem broadcasting");
                    }
                }
            }.start();
        }
    }

    public static void main(String[] args) {

        // args : ./ClientRMIVC  localnickanme  remote1  remote2 ... remoten
        //                         0            1         2           n
        int i;
        try {
            ClientRMIVC client = new ClientRMIVC(args[0]);

            // on se met a l'ecoute
            Naming.rebind(args[0], client);

            // on se connect aux autres usagers
            for (i = 1; i < args.length; i++)
            { 
                ClientInterfaceVC nclient = (ClientInterfaceVC) Naming.lookup(args[i]);
                nclient.register((ClientInterfaceVC)client);
                client.register((ClientInterfaceVC)nclient);
            }
            client.start();
        } catch (Exception e) {
            System.err.println("ClientRMIVC exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

class Msg implements Serializable
{
    private static final long serialVersionUID = 7526471155622776147L;

    private HashMap vc = new HashMap(); // vecteur d'horloge
    private String source = new String(); // emetteur du message
    private String msg = new String(); // le message

    public Msg(String nmsg, String nsource, HashMap nvc)
    {
        msg = nmsg;
        source = nsource;
        vc = nvc;
    }

    public String getMsg()
    {
        return msg;
    }

    public String getSource()
    {
        return source;
    }

    public HashMap getVC()
    {
        return vc;
    }
}

class MyQueue extends Vector
{
    static final long serialVersionUID = 42L;
    public void addQ(Msg msg) 
    {
        addElement(msg);
    }

    public Msg removeQ()
    {
        Msg msg = peek();
        removeElementAt(0);
        return msg;
    }

    public Msg peek()
    {
        if (size() == 0) throw new EmptyStackException();
        return (Msg) elementAt(0);

    }

    public boolean emptyQ() 
    {
        return size() == 0;
    }    
}

class Tableau {
    private Vector messages;

    public Tableau()
    {
        messages = new Vector();
    }

    public void addMsg(String msg)
    {
        messages.add(msg);
    }

    public void print()
    {
        int i;
        for (i = 0; i < messages.size(); i++)
        {
            System.out.println(messages.get(i)); 
        }
        System.out.println("\n");
    }
}