/// François-Régis Colin /// http://www.tls.cena.fr/products/ivy/ /// * /// (C) CENA /// * namespace IvyProbe { using System; using System.Collections; using System.Threading; using System.Text.RegularExpressions; using System.IO; using System.Configuration; using IvyBus; /// Console implementation of the ivyprobe test program. /// /// Mainly used for testing and debugging purpose public class IvyProbe { public virtual bool ExitOnDie { set { exitOnDie = value; } } public const String helpCommands = "Available commands:\n.die CLIENTNAME sends a die message\n.direct CLIENTNAME ID MESSAGE sends the direct message to the client, with a message id set to the numerical ID\n.bye quits the application\n.quit idem\n.list lists the available clients\n.ping sends a ping request if IVY_PING is enabled\n.bind REGEXP binds to a regexp at runtime\n.unbind REGEXP unbinds to a regexp at runtime"; public const String helpmsg = "usage: IvyProbe [options] [regexp]\n\t-b BUS\tspecifies the Ivy bus domain\n\t-n ivyname (default JPROBE)\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-t\ttime stamp each message\n\t-h\thelp\n\n\t regexp is a Perl5 compatible regular expression"; private TextReader in_Renamed; private volatile Thread looperThread; private Ivy bus; private bool timestamp, quiet, debug, exitOnDie = false; private Regex directMsgRE; [STAThread] public static void Main(String[] args) { String name = "C#PROBE"; bool quiet = false; bool timestamp = false; String domain = Ivy.getDomain(null); bool debug = false; if ( ConfigurationSettings.AppSettings["domain"] != null ) domain = ConfigurationSettings.AppSettings["domain"]; if ( ConfigurationSettings.AppSettings["name"] != null ) name = ConfigurationSettings.AppSettings["name"]; if ( ConfigurationSettings.AppSettings["quiet"] != null ) quiet = bool.Parse(ConfigurationSettings.AppSettings["quiet"]); if ( ConfigurationSettings.AppSettings["timestamp"] != null ) timestamp = bool.Parse(ConfigurationSettings.AppSettings["timestamp"]); if ( ConfigurationSettings.AppSettings["IVY_DEBUG"] != null ) debug = bool.Parse(ConfigurationSettings.AppSettings["IVY_DEBUG"] ); /* Getopt opt = new Getopt("Probe", args, "n:b:dqht"); int c; while ((c = opt.getopt()) != - 1) { switch (c) { case 'd': //UPGRADE_ISSUE: Method 'java.lang.System.getProperties' was not converted. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1000_javalangSystemgetProperties"' //System.Configuration.AppSettingsReader sysProp = System.getProperties(); //SupportClass.PutElement(sysProp, "IVY_DEBUG", "yes"); break; case 'b': domain = opt.Optarg; break; case 'n': name = opt.Optarg; break; case 'q': quiet = true; break; case 't': timestamp = true; break; case 'h': default: System.Console.Out.WriteLine(helpmsg); System.Environment.Exit(0); break; } } */ IvyProbe p = new IvyProbe(System.Console.In, timestamp, quiet, debug ); p.ExitOnDie = true; Ivy bus = new Ivy(name, name + " ready"); /* for (int i = opt.Optind; i < args.Length; i++) { if (!quiet) System.Console.Out.WriteLine("you want to subscribe to " + args[i]); bus.bindMsg(args[i], p); } */ if (!quiet) System.Console.Out.WriteLine(bus.domains(domain)); bus.start(domain); p.start(bus); } public IvyProbe(TextReader in_Renamed, bool timestamp, bool quiet, bool debug) { this.in_Renamed = in_Renamed; this.timestamp = timestamp; this.quiet = quiet; this.debug = debug; try { directMsgRE = new Regex("^\\.direct ([^ ]*) ([0-9]+) (.*)"); } catch (ArgumentException ree) { System.Console.Error.WriteLine("Regexp fatal error in the Probe program."); System.Console.Error.WriteLine(ree.StackTrace); System.Environment.Exit(0); } } public virtual void start(Ivy bus) { if (looperThread != null) throw new IvyException("Probe already started"); this.bus = bus; bus.clientConnected += new Ivy.ClientConnectedHandler( connect ); bus.clientDisconnected += new Ivy.ClientDisconnectedHandler( disconnect ); bus.dieReceived += new Ivy.DieHandler( die ); bus.directMessageReceived += new Ivy.DirectMessageHandler( directMessage ); looperThread = new Thread(new ThreadStart(Run)); looperThread.Name = "Keyboard Input Thread"; looperThread.Start(); } public void Run() { traceDebug("Thread started"); Thread thisThread = Thread.CurrentThread; String s; // "infinite" loop on keyboard input while (looperThread == thisThread) { s = in_Renamed.ReadLine(); if (s == null) break; parseCommand(s); } println("End of input. Good bye !"); bus.stop(); traceDebug("Probe Thread stopped"); } internal void parseCommand(String s) { Match result; traceDebug("parsing the [" + s + "] (length " + s.Length + ") string"); // crude parsing of the ".xyz" commands // TODO use regexps instends of String.lastIndexOf(String). Example // provided with .direct ! if (s.Length == 0) { println("-> Sent to " + bus.sendMsg(s) + " peers"); } else if ((result = directMsgRE.Match(s)).Success) { String target = result.Groups[1].ToString(); int id = Int32.Parse(result.Groups[2].ToString()); String message = result.Groups[3].ToString(); ArrayList v = bus.getIvyClientsByName(target); if (v.Count == 0) println("no Ivy client with the name \"" + target + "\""); for (int i = 0; i < v.Count; i++) ((IvyClient) v[i]).sendDirectMsg(id, message); return ; } else if (s.LastIndexOf(".die ") >= 0) { String target = s.Substring(5); System.Collections.ArrayList v = bus.getIvyClientsByName(target); if (v.Count == 0) println("no Ivy client with the name \"" + target + "\""); for (int i = 0; i < v.Count; i++) ((IvyClient) v[i]).sendDie(); } else if (s.LastIndexOf(".unbind ") >= 0) { String regexp = s.Substring(8); if (bus.unBindMsg(regexp)) { println("you want to unsubscribe to " + regexp); } else { println("you can't unsubscribe to " + regexp + ", your're not subscribed to it"); } } else if (s.LastIndexOf(".bind ") >= 0) { String regexp = s.Substring(6); println("you want to subscribe to " + regexp); bus.bindMsg(regexp, new Ivy.MessageHandler(receive)); } else if (s.LastIndexOf(".ping ") >= 0) { String target = s.Substring(6); ArrayList v = bus.getIvyClientsByName(target); if (v.Count == 0) { println("no Ivy client with the name \"" + target + "\""); } for (int i = 0; i < v.Count; i++) { ((IvyClient) v[i]).sendPing("test"); } } else if ((s.LastIndexOf(".quit") >= 0) || (s.LastIndexOf(".bye") >= 0)) { bus.stop(); System.Environment.Exit(0); } else if (s.LastIndexOf(".list") >= 0) { println(bus.IvyClients.Count + " clients on the bus"); foreach (IvyClient client in bus.IvyClients.Values ) { println("-> " + client.ApplicationName); } } else if (s.LastIndexOf(".help") >= 0) { println(helpCommands); } else if (s[0] == '.') { println("this command is not recognized"); println(helpCommands); } else { println("-> Sent to " + bus.sendMsg(s) + " peers"); } } // parseCommand private void connect(IvyClient client) { println(client.ApplicationName + " connected from "+client.RemoteAddress+":"+client.RemotePort); foreach (string re in client.Regexps ) { println(client.ApplicationName + " subscribes to " + re); } } private void disconnect(IvyClient client) { println(client.ApplicationName + " disconnected "); } private bool die(IvyClient client, int id) { println("received die msg from " + client.ApplicationName + " good bye"); /* I cannot stop the readLine(), because it is native code */ if (exitOnDie) System.Environment.Exit(0); return true; } private void directMessage(IvyClient client, int id, String arg) { println(client.ApplicationName + " direct Message " + id + arg); } private void receive(object data, IvyClient client, String[] args) { String s = client.ApplicationName + " sent"; for (int i = 0; i < args.Length; i++) s += " '" + args[i] + "'"; println(s); } private void traceDebug(String s) { if (debug) System.Console.Out.WriteLine("-->Probe<-- " + s); } private void println(String s) { if (!quiet) System.Console.Out.WriteLine(date() + s); } private String date() { if (!timestamp) return ""; System.DateTime d = System.DateTime.Now; return "[" + d + "] "; } } }