aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Ivy.java2
-rwxr-xr-xsrc/IvyClient.java34
-rw-r--r--src/Makefile2
-rw-r--r--src/PingCallback.java20
-rw-r--r--src/Probe.java20
5 files changed, 75 insertions, 3 deletions
diff --git a/src/Ivy.java b/src/Ivy.java
index 7e14619..7d26dff 100755
--- a/src/Ivy.java
+++ b/src/Ivy.java
@@ -112,7 +112,7 @@ public class Ivy implements Runnable {
* the library version, useful for development purposes only, when java is
* invoked with -DIVY_DEBUG
*/
- public static final String libVersion ="1.2.11";
+ public static final String libVersion ="1.2.12";
private boolean debug;
private ServerSocket app;
diff --git a/src/IvyClient.java b/src/IvyClient.java
index 85edfc8..5e71ccb 100755
--- a/src/IvyClient.java
+++ b/src/IvyClient.java
@@ -10,6 +10,8 @@
* created for each remote client.
*
* CHANGELOG:
+ * 1.2.12
+ * - Ping and Pong are back ...
* 1.2.8
* - no CheckRegexp anymore
* - synchronized(regexps) pour le match et le getParen():
@@ -90,6 +92,8 @@ public class IvyClient implements Runnable {
final static int SchizoToken = 6; /* avoid race condition in concurrent connexions, aka BeginRegexp in other implementations */
final static int DirectMsg = 7;/* the peer sends a direct message */
final static int Die = 8; /* the peer wants us to quit */
+ final static int Ping = 9; // from outer space
+ final static int Pong = 10;
final static String MESSAGE_TERMINATOR = "\n"; /* the next protocol will use \r */
final static String StartArg = "\u0002";/* begin of arguments */
final static String EndArg = "\u0003"; /* end of arguments */
@@ -101,6 +105,7 @@ public class IvyClient implements Runnable {
// private variables
private static Integer csMutex=new Integer(0);
private static int clientSerial=0; /* an unique ID for each IvyClient */
+ private Stack PCHStack = new Stack();
private String messages_classes[] = null;
private Ivy bus;
@@ -234,6 +239,16 @@ public class IvyClient implements Runnable {
sendString(Die,0,message);
}
+ /**
+ * triggers a Ping, and executes the callback
+ * @param pc the callback that will be triggerred (once) when the ponc is
+ * received
+ */
+ public void ping(PingCallback pc) throws IvyException {
+ PCHStack.push(new PingCallbackHolder(pc));
+ sendString(Ping,0,"");
+ }
+
///////////////////////////////////////////////////
//
// PROTECTED METHODS
@@ -471,6 +486,12 @@ public class IvyClient implements Runnable {
throw new IvyException(ioe.getMessage());
}
break;
+ case Pong:
+ ((PingCallbackHolder)PCHStack.pop()).run();
+ break;
+ case Ping:
+ sendString(Pong,0,"");
+ break;
case AddRegexp:
String regexp=s.substring(from,b.length);
if ( bus.CheckRegexp(regexp) ) {
@@ -569,4 +590,17 @@ public class IvyClient implements Runnable {
traceDebug(s);
}
+ private class PingCallbackHolder {
+ PingCallback pc;
+ long epoch;
+ PingCallbackHolder(PingCallback pc) {
+ this.pc=pc;
+ epoch=System.currentTimeMillis();
+ PCHStack.push(this);
+ }
+ void run() {
+ pc.pongReceived(IvyClient.this,(int)(System.currentTimeMillis()-epoch));
+ }
+ }
+
}
diff --git a/src/Makefile b/src/Makefile
index ecf9e33..1d89856 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ include ../java.mk
#.SUFFIXES: .java .class
#SRCS = *.java
- SRCS = IvyApplicationAdapter.java IvyApplicationListener.java IvyBindListener.java IvyClient.java IvyException.java Ivy.java IvyMessageListener.java IvyWatcher.java SelfIvyClient.java WaiterClient.java Waiter.java
+ SRCS = IvyApplicationAdapter.java IvyApplicationListener.java IvyBindListener.java IvyClient.java IvyException.java Ivy.java IvyMessageListener.java IvyWatcher.java SelfIvyClient.java WaiterClient.java Waiter.java PingCallback.java
TOOLS= IvyDaemon.java Probe.java After.java
OBJS = $(SRCS:.java=.class)
diff --git a/src/PingCallback.java b/src/PingCallback.java
new file mode 100644
index 0000000..ff3233b
--- /dev/null
+++ b/src/PingCallback.java
@@ -0,0 +1,20 @@
+package fr.dgac.ivy;
+
+/**
+ * this interface specifies the methods of an PingCallback
+ *
+ * @author Yannick Jestin
+ * @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
+ *
+ * Changelog:
+ * 1.2.12
+ */
+
+public interface PingCallback {
+ /**
+ * invoked when a Pong is received
+ * @param elapsedTime the elapsed time in milliseconds between the ping and
+ * the pong
+ */
+ void pongReceived(IvyClient ic,int elapsedTime);
+}
diff --git a/src/Probe.java b/src/Probe.java
index 0d3eed7..8ced8e5 100644
--- a/src/Probe.java
+++ b/src/Probe.java
@@ -7,6 +7,8 @@
* (c) CENA
*
* Changelog:
+ * 1.2.12
+ * - .ping is back
* 1.2.9
* - added the .time command
* - added the .bound *
@@ -71,7 +73,8 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin
".bound CLIENT\t\t\t* lists the subscriptions of a client, .bound * to get all\n"+
".bound\t\t\t\t* lists the probe's subscriptions\n"+
".where CLIENT\t\t\t* displays the host where a client runs\n"+
- ".time COUNT MESSAGE\t\t\t* measures the time it takes to send COUNT messages\n"
+ ".time COUNT MESSAGE\t\t\t* measures the time it takes to send COUNT messages\n"+
+ ".ping CLIENT\t\t\t* measures the roundtrip time in millisecond to reach a client\n"
;
public static final String helpmsg =
@@ -274,6 +277,21 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin
for (int i=0;i<v.size();i++) {
println("-> "+((IvyClient)v.elementAt(i)).getApplicationName());
}
+ } else if ( s.lastIndexOf(".ping ")>=0) {
+ String target=s.substring(6);
+ Vector v=bus.getIvyClientsByName(target);
+ if (v.size()==0) println("no Ivy client with the name \""+target+"\"");
+ for (int i=0;i<v.size();i++) {
+ try {
+ ((IvyClient)v.elementAt(i)).ping(new PingCallback() {
+ public void pongReceived(IvyClient ic,int elapsedTime){
+ System.out.println("round trip to"+ic.getApplicationName()+" "+elapsedTime+" ms");
+ }
+ });
+ } catch (IvyException ie) {
+ println("-> ping not sent, the remote client must have disconnected");
+ }
+ }
} else if ( s.lastIndexOf(".where ")>=0) {
String target=s.substring(7);
Vector v=bus.getIvyClientsByName(target);