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");
}
}