diff options
author | jacomi | 1999-04-15 09:47:30 +0000 |
---|---|---|
committer | jacomi | 1999-04-15 09:47:30 +0000 |
commit | 61fd14fd7d9f06491485d6a9e5c728ab457499ce (patch) | |
tree | 08b61af2fa350076bde5818a3361421ae442cd8f /src | |
parent | 23abb4b87c7e40ed259dd02f653516f60e55ade4 (diff) | |
download | ivy-java-61fd14fd7d9f06491485d6a9e5c728ab457499ce.zip ivy-java-61fd14fd7d9f06491485d6a9e5c728ab457499ce.tar.gz ivy-java-61fd14fd7d9f06491485d6a9e5c728ab457499ce.tar.bz2 ivy-java-61fd14fd7d9f06491485d6a9e5c728ab457499ce.tar.xz |
Initial revision
Diffstat (limited to 'src')
-rwxr-xr-x | src/Ivy$BCBA.class | bin | 0 -> 1731 bytes | |||
-rwxr-xr-x | src/Ivy.class | bin | 0 -> 7732 bytes | |||
-rwxr-xr-x | src/Ivy.java | 251 | ||||
-rwxr-xr-x | src/IvyApplicationAdapter.class | bin | 0 -> 961 bytes | |||
-rwxr-xr-x | src/IvyApplicationAdapter.java | 17 | ||||
-rwxr-xr-x | src/IvyApplicationListener.class | bin | 0 -> 464 bytes | |||
-rwxr-xr-x | src/IvyApplicationListener.java | 9 | ||||
-rwxr-xr-x | src/IvyClient.class | bin | 0 -> 8663 bytes | |||
-rwxr-xr-x | src/IvyClient.java | 322 | ||||
-rwxr-xr-x | src/IvyException.class | bin | 0 -> 439 bytes | |||
-rwxr-xr-x | src/IvyException.java | 5 | ||||
-rwxr-xr-x | src/IvyMessageListener.class | bin | 0 -> 338 bytes | |||
-rwxr-xr-x | src/IvyMessageListener.java | 6 | ||||
-rwxr-xr-x | src/IvyWatcher.class | bin | 0 -> 5724 bytes | |||
-rwxr-xr-x | src/IvyWatcher.java | 166 | ||||
-rwxr-xr-x | src/TestIvy$APPCB.class | bin | 0 -> 1852 bytes | |||
-rwxr-xr-x | src/TestIvy$BUSCB.class | bin | 0 -> 1234 bytes | |||
-rwxr-xr-x | src/TestIvy$MSGCB.class | bin | 0 -> 1295 bytes | |||
-rwxr-xr-x | src/TestIvy$REGCB.class | bin | 0 -> 1953 bytes | |||
-rwxr-xr-x | src/TestIvy$SENDCB.class | bin | 0 -> 1395 bytes | |||
-rwxr-xr-x | src/TestIvy$WCCB.class | bin | 0 -> 1171 bytes | |||
-rwxr-xr-x | src/TestIvy.class | bin | 0 -> 3718 bytes | |||
-rwxr-xr-x | src/TestIvy.java | 115 |
23 files changed, 891 insertions, 0 deletions
diff --git a/src/Ivy$BCBA.class b/src/Ivy$BCBA.class Binary files differnew file mode 100755 index 0000000..4f3a45f --- /dev/null +++ b/src/Ivy$BCBA.class diff --git a/src/Ivy.class b/src/Ivy.class Binary files differnew file mode 100755 index 0000000..e57e238 --- /dev/null +++ b/src/Ivy.class diff --git a/src/Ivy.java b/src/Ivy.java new file mode 100755 index 0000000..6fce37b --- /dev/null +++ b/src/Ivy.java @@ -0,0 +1,251 @@ +// +// API de connexion au bus logiciel ivy +// +// + +package fr.dgac.ivy ; + +import java.net.*; +import java.io.*; +import java.util.Vector; +import java.util.StringTokenizer; + +public class Ivy implements Runnable, IvyApplicationListener { + + static private boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; + + public static final int DEFAULT_PORT = 2010 ; + public static final String DEFAULT_DOMAIN = "127.255.255.255:"+DEFAULT_PORT; + public String appName; + private boolean ivyRunning = false; + private String ready_message = null; + private Vector regexp_out; + private ServerSocket app; + private IvyWatcher watch; + private Thread server; + private Vector clients; + private Vector callbacks; + private Vector ivyApplicationListenerList; + private String messages_classes[] = null; + private int myport; /* Application port number */ + + public synchronized boolean ivyRunning(){ + return ivyRunning; + } + // constructeur + public Ivy( String name, String message, IvyApplicationListener appcb) + { + appName = name; + ivyApplicationListenerList = new Vector(); + ready_message = message; + callbacks = new Vector(); + clients = new Vector(); + regexp_out = new Vector(); + if ( appcb != null ) + ivyApplicationListenerList.addElement( appcb ); + } + + void classes( String msg_classes[] ) { + messages_classes = msg_classes; + } + public Vector getRegexpOut() { + return regexp_out; + } + public String getReadyMessage() { + return ready_message; + } + + void addClient( Socket socket ) throws IOException { + IvyClient client = new IvyClient( this, socket); + clients.addElement( client ); + } + + void removeClient( IvyClient client ) { + clients.removeElement( client ); + } + + void callCallback( IvyClient client, int msgid, String msgarg ) { + IvyMessageListener callback; + String args[]; + if ( (msgid <0) || (msgid > callbacks.size()) ) { + traceDebug("(callCallback) Not regexp matching id "+msgid); + return; + } + callback = (IvyMessageListener)callbacks.elementAt(msgid); + StringTokenizer st = new StringTokenizer(msgarg, IvyClient.EndArg); + args = new String[st.countTokens()]; + int i=0; + while (st.hasMoreTokens()) + { + args[i++] = st.nextToken(); + } + callback.receive( client, args ); + } + + public int getApplicationPort() { + return myport; + } + + public int sendMsg( String message ) { + int count = 0; + // envoie le message à tous les clients du bus + // TODO: il faudrait mettre une Thread emission par client */ + for ( int i = 0 ; i < clients.size(); i++ ) { + IvyClient client = (IvyClient)clients.elementAt(i); + count += client.sendMsg( message ); + } + return count; + } + + public int bindMsg(String regexp, IvyMessageListener callback ) { + // associe une nouvelle regexp à un nouveau callback + regexp_out.addElement( regexp ); + callbacks.addElement( callback ); + int id = regexp_out.indexOf( regexp ); + /* indique aux autres clients la nouvelle regexp */ + for ( int i = 0 ; i < clients.size(); i++ ) { + IvyClient client = (IvyClient)clients.elementAt(i); + client.sendRegexp(id, regexp ); + } + return id; + } + + public void unBindMsg(int id) { + // TODO: Est ce que la suppression d'1 element + // ne provoque pas le tassement + // et donc la modif des autres indexes? + if ( id >=0 && id < regexp_out.size() ) + { + regexp_out.removeElementAt( id ); + callbacks.removeElementAt( id ); + + for ( int i = 0 ; i < clients.size(); i++ ) + { + IvyClient client = (IvyClient)clients.elementAt(i); + client.delRegexp(id ); + } + } + } + /* gestion des applications listener et callback associe */ + public int addApplicationListener(IvyApplicationListener callback){ + // associe une nouvelle regexp à un nouveau callback + ivyApplicationListenerList.addElement( callback ); + int id = ivyApplicationListenerList.indexOf( callback ); + return id; + } + public void removeApplicationListener( int id ) { + ivyApplicationListenerList.removeElementAt(id); + } + public void connect(IvyClient client){ + for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) + { + IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); + listener.connect(client); + } + } + public void disconnect(IvyClient client){ + for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) + { + IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); + listener.disconnect(client); + } + } + public void die(IvyClient client, int id){ + for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) + { + IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); + listener.die(client, id); + } + } + public void directMessage( IvyClient client, int id,String msgarg ){ + for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) + { + IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); + listener.directMessage(client,id, msgarg); + } + } + + public static String getDomain(String domainbus) throws IvyException { + if ( domainbus == null ) + domainbus = System.getProperty("IVYBUS"); + if ( domainbus == null ) + domainbus = DEFAULT_DOMAIN; + return domainbus; + } + public void start(String domainbus) throws IvyException { + try { + app = new ServerSocket(0); + myport = app.getLocalPort(); + } catch (IOException e) { + throw new IvyException("ne peut pas ouvrir la socket server" + e ); + } + /* Start watcher thread */ + watch = new IvyWatcher(this); + traceDebug("BUS TCP: "+myport); + ivyRunning = true; + server = new Thread( this); + /* Start ivy server thread */ + server.start(); + /* Send ivy helo msg */ + watch.sendStart(getDomain(domainbus)); + } + + public void stop() { + try { + ivyRunning = false; + watch.close(); /* Stop watcher thread */ + app.close(); /* Stop ivy server thread */ + for ( int i = 0 ; i < clients.size(); i++ ) { + IvyClient client = (IvyClient)clients.elementAt(i); + client.close("Ivy Stopping...");/* Stop client thread */ + } + } catch ( IOException e ) { + traceDebug("ioexception Stop "); + } + clients.removeAllElements(); + } + + boolean CheckRegexp( String exp ) { + /* accepte tout par default */ + int i; + boolean regexp_ok = true; + if ( exp.startsWith( "^" ) && messages_classes != null ) { + regexp_ok = false; + for ( i = 0 ; i < messages_classes.length; i++ ) { + if ( messages_classes[i].equals( exp.substring(1)) ) return true; + } + } + return regexp_ok; + } + + public boolean checkConnected( IvyClient clnt ) { + if ( clnt.appPort == 0 ) return false; + for ( int i = 0 ; i < clients.size(); i++ ) { + IvyClient client = (IvyClient)clients.elementAt(i); + if ( clnt != client && client.sameClient( clnt ) ) return true; + } + return false; + } + + public void run() { + Socket socket; + while( ivyRunning() ) { + try { + socket = app.accept(); + addClient( socket ); + } catch( IOException e ) { + /* Normal terminaison si socket close */ + /* TODO: et les autres */ + traceDebug("Error IvyServer exception: " + e.getMessage()); + } + } + } + + private void traceDebug(String s){ + if (debug) System.out.println("-->ivy<-- "+s); + } + + + + +} // class Ivy diff --git a/src/IvyApplicationAdapter.class b/src/IvyApplicationAdapter.class Binary files differnew file mode 100755 index 0000000..a8727aa --- /dev/null +++ b/src/IvyApplicationAdapter.class diff --git a/src/IvyApplicationAdapter.java b/src/IvyApplicationAdapter.java new file mode 100755 index 0000000..16491b5 --- /dev/null +++ b/src/IvyApplicationAdapter.java @@ -0,0 +1,17 @@ +/* +** +** BusCallbackAdapter +** +** la même pratique que pour l awt 1.1. Quand on ne veut implémenter qu une +** des trois fonctions membres, il suffit d étendre l'adapter +** pas de constructeur ... c'est donc une class abstraite +*/ + +package fr.dgac.ivy; + +public abstract class IvyApplicationAdapter implements IvyApplicationListener { + public void connect( IvyClient client ) { } + public void disconnect( IvyClient client ) { } + public void die( IvyClient client ) { } + public void directMessage( IvyClient client, int id,String msgarg ) {} +} diff --git a/src/IvyApplicationListener.class b/src/IvyApplicationListener.class Binary files differnew file mode 100755 index 0000000..d7596e1 --- /dev/null +++ b/src/IvyApplicationListener.class diff --git a/src/IvyApplicationListener.java b/src/IvyApplicationListener.java new file mode 100755 index 0000000..3dacc93 --- /dev/null +++ b/src/IvyApplicationListener.java @@ -0,0 +1,9 @@ +package fr.dgac.ivy; + +public interface IvyApplicationListener +{ + public abstract void connect(IvyClient client); + public abstract void disconnect(IvyClient client); + public abstract void die(IvyClient client, int id); + public abstract void directMessage( IvyClient client, int id,String msgarg ); +} diff --git a/src/IvyClient.class b/src/IvyClient.class Binary files differnew file mode 100755 index 0000000..e5a2a90 --- /dev/null +++ b/src/IvyClient.class diff --git a/src/IvyClient.java b/src/IvyClient.java new file mode 100755 index 0000000..8ec226d --- /dev/null +++ b/src/IvyClient.java @@ -0,0 +1,322 @@ +/* +** +** IvyClient +** Wed Aug 27 15:02:00 MET DST 1997 -> rajout des fonction ping & pong +** +** correction: un Die va faire finir le Thread, pas l'*ensemble* +*/ + +package fr.dgac.ivy ; + +import java.lang.Thread; +import java.net.*; +import java.io.*; +import java.util.Date; +import java.util.Vector; +import java.util.StringTokenizer; +import gnu.regexp.*; + +public class IvyClient extends Thread { + + // les types de messages + public final static int Bye = 0; /* l'application emettrice se termine */ + public final static int AddRegexp = 1;/* expression reguliere d'un client */ + public final static int Msg = 2 ; /* message reel */ + public final static int Error = 3; /* error message */ + public final static int DelRegexp = 4;/* Remove expression reguliere */ + public final static int EndRegexp = 5;/* fin de liste regexp */ + public final static int StartRegexp = 6;/* debut des expressions */ + public final static int DirectMsg = 7;/* message direct a l'appli */ + public final static int Die = 8; /* demande de terminaison de l'appli */ + public final static int Ping = 9; /* demande de réponse pong */ + public final static int Pong = 10; /* réponse au ping */ + + public final static String StartArg = "\002";/* separateur debut args */ + public final static String EndArg = "\003"; /* separateur inter arguments */ + + protected String appName; + public int appPort; + + // gestion du protocole ping + long lastRead = 0; + long pingDate = 0 ; + long pingLag =0 ; + + Ivy bus; + Socket socket; + BufferedReader in; + OutputStream out; + + Vector regexp_in; + Vector regexp_id; + + static private boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; + + IvyClient( Ivy bus, Socket socket ) throws IOException { + appName = "Unkown"; + appPort = 0; + this.bus = bus; + this.socket = socket; + lastRead = (new Date()).getTime(); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + out = socket.getOutputStream(); + regexp_in = new Vector(); + regexp_id = new Vector(); + sendService( bus.getRegexpOut() ); + start(); + } + + public InetAddress getRemoteAddress() { return socket.getInetAddress(); } + public String getApplicationName() { return appName ; } + + void sendBuffer( String buffer ) { + buffer += "\n"; + try { + out.write(buffer.getBytes() ); + out.flush(); + } catch ( IOException e ) + { + // TODO: write error + } + } + void send( int type, int id, String arg) { + String buffer = type+" "+id+StartArg+arg; + sendBuffer(buffer ); + } + + void sendRegexp( int id, String regexp ) + { + send( AddRegexp,id,regexp); + } + + public void sendDie( ) + { + send( Die,0,""); + } + + public void sendDie(String message) + { + send( Die,0,message); + } + + void sendPing() + { + pingDate = (new Date()).getTime(); + // on marque le message par la date actuelle + send( Ping, 0, String.valueOf(pingDate) ); + } + + void sendService( Vector regexps ) + { + send( StartRegexp, bus.getApplicationPort(), bus.appName); + for ( int id = 0 ; id < regexps.size(); id++ ) + { + String regexp; + regexp = (String)regexps.elementAt(id); + sendRegexp( id,regexp); + } + send( EndRegexp,0, ""); + } + + void send( int type, Integer id, int nbsub, REMatch result) + { + String buffer = type+" "+id+StartArg; + traceDebug ( "Send matching result \n" ); + // ????Start at 1 because group 0 represent entire matching + for(int sub = 1; sub <= nbsub; sub++) { + if (result.getSubStartIndex(sub) > -1) { + buffer += result.toString(sub)+EndArg; + traceDebug( "Send arg "+result.toString(sub)); + } + } + sendBuffer( buffer ); + } + + public int sendMsg( String message ) + { + REMatch result; + RE regexp; + Integer id; + int count = 0; + for ( int i = 0 ; i < regexp_in.size(); i++ ) + { + regexp = (RE)regexp_in.elementAt(i); + id = (Integer) regexp_id.elementAt(i); + result = regexp.getMatch(message); + if ( result != null ) + { + send( Msg,id,regexp.getNumSubs(),result); + count ++; + } + } + return count; + } + + void close(String msg) throws IOException + { + traceDebug( msg ); + socket.close(); + //stop(); + } + + public boolean sameClient( IvyClient clnt ) + { + if ( appPort != 0 && appPort == clnt.appPort ) { + if ( getRemoteAddress() == clnt.getRemoteAddress() ) return true; + } + return false; + } + public void delRegexp( int id ) + { + send( DelRegexp,id,""); + } + public void run() + { + + String msg = null; + String token = null; + int i; + int msgtype; /* type du dernier message recu */ + Integer msgid; /* id du dernier message recu */ + String msgarg = null; /* argument du dernier message recu */ + RE regexp = null; /* regexp compile */ + + try { + + traceDebug("Connected from "+ + socket.getInetAddress().getHostName()+":"+socket.getPort()); + + parseInput: + while( (msg = in.readLine()) != null ) { + + /* étape un : extrait le message */ + lastRead = (new Date()).getTime(); + StringTokenizer st = new StringTokenizer(msg); + traceDebug("Receive msg '"+msg+"'"); + if ( ! st.hasMoreTokens()) { + close("Bad format no type '"+msg+"'"); + break; + } + token = st.nextToken(); + if ( token.length() == 0 ) { + close("Bad format no type '"+msg+"'"); + break; + } + try { msgtype = Integer.parseInt( token ); } + catch ( NumberFormatException e ) { + close("Bad format error parsing type'"+msg+"'"); + break; + } + if ( ! st.hasMoreTokens()) { + close("Bad format no id '"+msg+"'"); + break; + } + msgid = Integer.valueOf( st.nextToken(StartArg) ); + if ( st.hasMoreTokens()) { + msgarg = st.nextToken("\n"); + } + + /* étape deux : traitement adapté */ + switch( msgtype ){ + case Bye: break; + case AddRegexp: + if ( bus.CheckRegexp( msgarg ) ) { + // Attempt to compile the pattern. If the pattern is not valid, + // report the error and exit. + try { + regexp = new RE(msgarg); + if ( regexp.getNumSubs()!= 0 ) + { + /* check to see if any subexp */ + /* these are needed to send msg */ + regexp_in.addElement( regexp ); + regexp_id.addElement( msgid ); + } + else System.err.println("Bad pattern: No () groups"); + } catch (REException e) { + System.err.println("Bad pattern: "+e.getMessage()); + } + } else System.err.println("Warning exp='"+ + msgarg+"' can't match removing from "+appName); + break; + case DelRegexp: + i = regexp_id.indexOf( msgid ); + if ( i >=0 ) + { + regexp_in.removeElementAt(i); + regexp_id.removeElementAt(i); + } + break; + case EndRegexp: + /* + ** call application callback avec event Connected + */ + bus.connect( this ); + if ( bus.getReadyMessage() != null ) + sendMsg( bus.getReadyMessage() ); + break; + case Msg: + /* + ** call callback avec les arguments + */ + bus.callCallback( this, msgid.intValue(), msgarg ); + break; + case Error: + traceDebug("Error msg "+msgid+" "+msgarg); + break; + case StartRegexp: + appName=msgarg; + appPort=msgid.intValue(); + if ( bus.checkConnected( this ) ) + close( "Quitting Application already connected" ); + break; + case DirectMsg: + traceDebug("Direct Message id="+msgid+" msg='"+msgarg+"'"); + + /* + ** call directCallback avec les arguments + */ + bus.directMessage( this, msgid.intValue(), msgarg ); + break; + case Die: + traceDebug("Die Message received . argh !"); + /* + ** call diecallBack aavant de quitter + */ + bus.die( this,msgid.intValue()); + break parseInput; + case Ping: + traceDebug("Ping Message"); + // répond avec le même argument .. Pour le moment c'est inutile + send(Pong,0,msgarg); + break; + case Pong: + // calcul du lag en millisecondes + traceDebug("Pong Message"); + pingLag = (new Date()).getTime() - pingDate ; + break; + default: + System.err.println("*** IvyClient *** unhandled msg type "+ + msgtype+" "+msgid+msgarg); + break; + } // switch sur le type de message + } // while readline + // plus rien à lire .... ou alors break donc erreur + traceDebug("zarbi Disconnected from "+ + socket.getInetAddress().getHostName()+":"+socket.getPort()); + } catch ( IOException e ) { + traceDebug("ioexception Disconnected from "+ + socket.getInetAddress().getHostName()+":"+socket.getPort()); + } + /* je meurs en tant que client du bus */ + /* mais avant, j'exécute mon application callback perso */ + bus.disconnect( this ); + bus.removeClient( this ); + } // run + + public String From() { return socket.toString(); } + + private void traceDebug(String s){ + if (debug) System.out.println("-->ivyclient<-- "+s); + } +} // class IvyClient diff --git a/src/IvyException.class b/src/IvyException.class Binary files differnew file mode 100755 index 0000000..e8c8a7e --- /dev/null +++ b/src/IvyException.class diff --git a/src/IvyException.java b/src/IvyException.java new file mode 100755 index 0000000..263631b --- /dev/null +++ b/src/IvyException.java @@ -0,0 +1,5 @@ +package fr.dgac.ivy; + +public class IvyException extends Exception { + public IvyException(String s) { super(s); } +} diff --git a/src/IvyMessageListener.class b/src/IvyMessageListener.class Binary files differnew file mode 100755 index 0000000..2f5d5ce --- /dev/null +++ b/src/IvyMessageListener.class diff --git a/src/IvyMessageListener.java b/src/IvyMessageListener.java new file mode 100755 index 0000000..3fd032b --- /dev/null +++ b/src/IvyMessageListener.java @@ -0,0 +1,6 @@ +package fr.dgac.ivy; + +public interface IvyMessageListener +{ + public abstract void receive(IvyClient client, String[] args); +} diff --git a/src/IvyWatcher.class b/src/IvyWatcher.class Binary files differnew file mode 100755 index 0000000..a8d714e --- /dev/null +++ b/src/IvyWatcher.class diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java new file mode 100755 index 0000000..21311e9 --- /dev/null +++ b/src/IvyWatcher.java @@ -0,0 +1,166 @@ +/* +* +* IvyWatcher : gestion des messages UDP pour annoncer les arrivées +* +*/ +package fr.dgac.ivy ; + +import java.lang.Thread; +import java.net.*; +import java.io.*; +import java.util.StringTokenizer; +import gnu.regexp.*; +import java.util.Vector; +public class IvyWatcher extends Thread { + Ivy bus; /* master bus controler */ + DatagramSocket broadcast; /* supervision socket */ + private Vector domainaddrList; + private static boolean debug = (System.getProperty("IVY_DEBUG")!=null); + + public void close() { + broadcast.close(); + } + private void sendBroadcast( String data, String net ) throws IvyException + { + DatagramPacket packet; + // transformation en forme de broadcast w.x.y.z en w.x.y.255 + try { + // simple trick to expend to 255 thank's Alex + net += ".255.255.255"; + RE exp = new RE( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*"); + net = exp.substitute( net , "$1" ); + } catch ( REException e ){ + throw new IvyException("Bad broascat addr"); + } + // broadcast sur l'adresse iadr + try { + InetAddress iaddr = InetAddress.getByName(net); + domainaddrList.addElement( iaddr ); + packet = new DatagramPacket( + data.getBytes(), + data.length(), + iaddr, + broadcast.getLocalPort() ); + broadcast.send( packet ); + } catch ( UnknownHostException e ) { + throw new IvyException("Broadcast sur réseau inconnu " + e ); + } catch ( IOException e ) { + throw new IvyException("broadcast send erreur " + e ); + } + } + public void sendStart(String domain) throws IvyException { + String domainaddr; + // parse Domain to get port number + int port; + int sep_index = domain.lastIndexOf( ":" ); + if ( sep_index == -1 ) + { + port = bus.DEFAULT_PORT; + domainaddr = domain; + } + else + { + port = Integer.parseInt( domain.substring( sep_index +1 )); + domainaddr = domain.substring(0,sep_index); + } + // create the UDP socket + try { + broadcast = new MulticastSocket(port ); + } catch ( IOException e ) { + throw new IvyException("IvyWatcher erreur I/O" + e ); + } + // start UDP receiver + start(); + // send hello world on UDP sockets + String hello = "3 "+bus.getApplicationPort()+"\n"; + StringTokenizer st = new StringTokenizer(domainaddr," \t:,"); + while ( st.hasMoreTokens()) { + sendBroadcast( hello, st.nextToken() ); + } + } + + IvyWatcher(Ivy bus) throws IvyException { + this.bus = bus; + domainaddrList = new Vector(); + } + + public void run() { + DatagramPacket packet; + byte buf[] = new byte[256]; + int port; + int version; + /**/ + traceDebug("IvyWatcher waiting for Broadcast"); + while( bus.ivyRunning() ) + { + try { + /* receive antoher application port */ + packet = new DatagramPacket(buf, 256); + broadcast.receive( packet ); + String msg = new String(packet.getData()) ; + InetAddress remotehost = packet.getAddress(); + traceDebug("BUSWATCHER Receive Broadcast from:"+ + remotehost.getHostName()+ + ":"+packet.getPort() + +"'"+msg+"'"); + // check if remoteaddr is in our broadcast domain list + if ( !isInDomain( remotehost ) ) + continue; + StringTokenizer st = new StringTokenizer(msg); + if ( ! st.hasMoreTokens()) { + System.err.println("Bad format "+msg); + continue; + } + version = Integer.parseInt( st.nextToken() ); + if ( ! st.hasMoreTokens()) { + System.err.println("Bad format "+msg); + continue; + } + port = Integer.parseInt( st.nextToken() ); + // TODO: More checking here host port domain etc.... + if ( (bus.getApplicationPort() == port) ) + { + continue; + } + traceDebug("BUSWATCHER Broadcast de " + +packet.getAddress().getHostName()+":"+packet.getPort()+" port "+port); + /* connect to the application */ + try { + Socket socket = new Socket( remotehost, port ); + bus.addClient( socket ); + } catch ( UnknownHostException e ) { + System.err.println("Unkonwn host "+remotehost); + } catch ( IOException e) { + System.err.println("can't connect to "+remotehost+" port "+port); + } + + } catch ( IOException e ) { + // TODO: comment distinger la fin normale de 'erreur + /* fermeture de la socket arret normal */ + traceDebug("Error IvyWatcher exception: " + e.getMessage()); + } + }// end while + } + + private void traceDebug(String s){ + if (debug) System.out.println("-->ivywatcher<-- "+s); + } + private boolean isInDomain( InetAddress host ){ + byte rem_addr[] = host.getAddress(); + for ( int i = 0 ; i < domainaddrList.size(); i++ ) + { + byte addr[] = ((InetAddress)domainaddrList.elementAt(i)).getAddress(); + int j ; + for ( j = 0 ; j < 4 ; j++ ) + if ( (addr[j] != -1) && (addr[j] != rem_addr[j]) ) break; + if ( j == 4 ) + { + traceDebug( "host " + host + " is in domain\n" ); + return true; + } + } + traceDebug( "host " + host + " Not in domain\n" ); + return false; + } +} + diff --git a/src/TestIvy$APPCB.class b/src/TestIvy$APPCB.class Binary files differnew file mode 100755 index 0000000..18f8f64 --- /dev/null +++ b/src/TestIvy$APPCB.class diff --git a/src/TestIvy$BUSCB.class b/src/TestIvy$BUSCB.class Binary files differnew file mode 100755 index 0000000..59b6c0d --- /dev/null +++ b/src/TestIvy$BUSCB.class diff --git a/src/TestIvy$MSGCB.class b/src/TestIvy$MSGCB.class Binary files differnew file mode 100755 index 0000000..4121e41 --- /dev/null +++ b/src/TestIvy$MSGCB.class diff --git a/src/TestIvy$REGCB.class b/src/TestIvy$REGCB.class Binary files differnew file mode 100755 index 0000000..0de2d5a --- /dev/null +++ b/src/TestIvy$REGCB.class diff --git a/src/TestIvy$SENDCB.class b/src/TestIvy$SENDCB.class Binary files differnew file mode 100755 index 0000000..f3244aa --- /dev/null +++ b/src/TestIvy$SENDCB.class diff --git a/src/TestIvy$WCCB.class b/src/TestIvy$WCCB.class Binary files differnew file mode 100755 index 0000000..a85a948 --- /dev/null +++ b/src/TestIvy$WCCB.class diff --git a/src/TestIvy.class b/src/TestIvy.class Binary files differnew file mode 100755 index 0000000..e71517e --- /dev/null +++ b/src/TestIvy.class diff --git a/src/TestIvy.java b/src/TestIvy.java new file mode 100755 index 0000000..46f484d --- /dev/null +++ b/src/TestIvy.java @@ -0,0 +1,115 @@ +package fr.dgac.ivy ; + +import java.awt.* ; +import java.awt.event.* ; + +class TestIvy extends Panel implements IvyApplicationListener{ + + Ivy bus ; + String regexp ; + TextField tfRegex, tfSend ; + TextArea ta ; + Button buApply, buSend, buClear ; + int regexp_id; + public TestIvy() throws IvyException { + super(new BorderLayout()); + regexp = ""; + // un textarea au centre + ta = new TextArea(); + ta.setEditable(false); + add(ta,BorderLayout.CENTER); + // une zone regex au nord + Panel p = new Panel(new BorderLayout()); + p.add(new Label("Regex:"),BorderLayout.WEST); + tfRegex = new TextField(regexp); + tfRegex.addActionListener(new REGCB()); + p.add(tfRegex,BorderLayout.CENTER); + add(p,BorderLayout.NORTH); + // une zone messages au sud + p = new Panel(new BorderLayout()); + p.add(new Label("Msg:"),BorderLayout.WEST); + tfSend = new TextField(""); + tfSend.addActionListener(new SENDCB()); + p.add(tfSend,BorderLayout.CENTER); + add(p,BorderLayout.SOUTH); + bus = new Ivy("JAVA TESTBUS","Testbus ridi",this); + bus.start(null); + append( "Ivy Domain: "+ bus.getDomain(null) ); + } + + public void stop() { + bus.stop(); + } + public void connect(IvyClient client) { + append(client.getApplicationName() + " connected " ); + } + public void disconnect(IvyClient client) { + append(client.getApplicationName() + " disconnected " ); + } + public void die(IvyClient client, int id) { + append(client.getApplicationName() + " die "+ id ); + } + public void directMessage(IvyClient client, int id, String arg) { + append(client.getApplicationName() + " direct Message "+ id + arg ); + } + /* inner */ class REGCB implements ActionListener, IvyMessageListener { + public void actionPerformed(ActionEvent e) { + // enlever l'ancienne regex + bus.unBindMsg(regexp_id); + // ajoute la nouvelle regex + regexp=tfRegex.getText(); + regexp.trim(); + regexp_id = bus.bindMsg(regexp,this); + tfRegex.setText(""); + } + public void receive(IvyClient client, String[] args) { + String out="client " + client.getApplicationName() + " envoie: [ "; + for (int i=0;i<args.length;i++) + out=out+args[i]+ ((i<args.length-1)?" , ":""); + out = out + " ]"; + append(out); + } + } + + /* inner */ class SENDCB implements ActionListener { + public void actionPerformed(ActionEvent e) { + int count; + String tosend = tfSend.getText(); + tfSend.setText(""); + count = bus.sendMsg(tosend); + append("Sending '" + tosend + "' count " + count ); + + } + } + + private void append(String s) { + // je mettrais bien la date, aussi. + ta.append(s + "\n"); + } + + public static void main(String[] args) throws IvyException { + TestIvy tb = new TestIvy(); + Frame f = new Frame("TestIvy"); + f.addWindowListener( tb.new WCCB(f,tb)) ; + f.add(tb, BorderLayout.CENTER); + f.pack(); + f.setVisible(true); + } + + /* inner */ class WCCB extends WindowAdapter { + private Frame f; + public WCCB(Frame f, TestIvy b) { + this.f=f; + } + public void windowClosing(WindowEvent e) { + f.setVisible(false); + bus.stop(); + bus = null; + f.dispose(); + System.exit(0); + } + } + +} + +// EOF |