N.B. Callback, when your client is behind a firewall, usually
does not work. There are ways around this that involve the client opening a port
outside the firewall. There are many discussions on how to do a callback behind a firewall
on the Sun Developer RMI forum. Go to the forums at Sun Developer and choose, RMI.
The Tymeac Server is an RMI Server. It does not communicate with any other RMI,
CORBA, etc. Servers. For ways to do this you may see our discussion on load balancing.
Tymeac Clients communicate with the Tymeac Server using RMI. If it is necessary
for a Processing Application Class, running within the Tymeac Server, to communicate with
another RMI Server, than that Processing Application Class must have a reference to the
other RMI Server, (remote object.)
This reference to a remote object is the key to RMI communication. How the
Processing Application Class obtains the reference is application dependent.
- The client may pass the name of the other RMI Server to the Processing Application Class
and the Class may use the RMI or JNDI registry to "lookup" the name.
- On a local system where the client and server are within the same machine, the client
may serialize the reference to the remote object, write it to a file and pass the file
name to the Processing Application Class which then reads the file.
- The client may pass the reference to the remote object within a serialized class to the
Processing Application Class and the Class may use RMI method invocation directly.
- Other methods may come from your imagination.
It is the third way that we demonstrate with the following source code.
The java.io.Serializable class that contains the reference to the remote object is: TyDemoCallbackParm.
The Tymeac Client that becomes an RMI Server is: TyDemoClient_Callback.
The Interface is: TyDemoCallback.
The implementation of the interface is: TyDemoCallbackImpl.
The Processing Application Classes are similar to the other, non-callback, classes in
the demonstration package, these are: DemoCallback1-3 and DemoAgentCallback
.
The Tymeac Client that becomes an RMI Server, TyDemoClient_Callback,
is the only significantly different code in the group.
// new object of the Callback implementation Class
TyDemoCallbackImpl impl = new TyDemoCallbackImpl();
TyDemoClient_Callback is started on the command line. Therefore, its main() method is
static. In order to get a reference to a remote object, (TyDemoCallbackImpl), this
statement is necessary.
try {
// make me an RMI Server
UnicastRemoteObject.exportObject(impl);
}
catch (java.rmi.RemoteException e) {
// say error
System.out.println("caught RemoteException from
exportObject");
// done
return;
}
The export() makes this JVM an RMI Server. That is --- One that may execute code
from the request of a client. This single line starts many threads necessary to
accomplish this. Of some concern is a thread known as "keep alive". The
purpose of this thread is to never end and in so doing, it keeps the RMI Server running
forever. Therefore, to end this process, one must use System.exit(0) instead of
"return".
// new pass parm
TyDemoCallbackParm parm = new TyDemoCallbackParm( impl, pass);
In addition to the data necessary for the Processing Application Classes to do the
work, this class also contains a reference to the remote object so that the Output Agent
Class, DemoAgentCallback, may send the result back to the Tymeac Client.
Compile all eight of these classes and place the classes in proper directories.
Run RMIC on the TyDemoCallbackImpl. Place the _Stub class in a
directory where both the Tymeac Client, Tymeac Server and RMI Registry may find it. If you
use the codebase option, then place the class in that directory.
Update the TymeacUserQueues and Functions with data from the <home>/source/callData.txt
file, recompile these source java files and place the classes in proper directories.
Start the RMI Registry.
Start the Tymeac Server.
Open a command line window. Execute java [-Djava -cp that which is necessary] TyDemoClient_Callback.
The result should be, (not necessarily in this order):
- The normal return from a Tymeac asyncRequest(),
- The String: "DemoAgentCallback ==> plus the normal Tymeac return
data"