From 61fd14fd7d9f06491485d6a9e5c728ab457499ce Mon Sep 17 00:00:00 2001 From: jacomi Date: Thu, 15 Apr 1999 09:47:30 +0000 Subject: Initial revision --- src/IvyClient.java | 322 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100755 src/IvyClient.java (limited to 'src/IvyClient.java') 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 -- cgit v1.1