// $Id: ClientRMI.java,v 3.4 1998/12/09 20:06:15 mk2z Exp $
////////////////////////////////////////////////////////////////////////////
//
// File: ClientRMI.java
//
// Purpose: This is the main communications module on the clients side. Upon
// getting started, it looks up to see whether a Registry exists on
// a specified port/IP.
// It also implements the ClientRMIIface and the interface agreed upon
// with the ClientEngine.
//
// Summary of incoming calls from the ServerRMI:
//
// ReceiveMap
// Shutdown
//
// Summary of outgoing calls (incoming from ClientEngine):
//
// SetClientID -> RegisterClient -> (ServerRMI)
// SendChanges -> ReceiveModule -> (ServerRMI)
//
// Authors:
// Orim Miro Kresonja mk2z@virginia.edu
// txe Travis Emmitt
//
// Modifications:
// 02-NOV-1998 Orim Initial creation
// 04-NOV-1998 txe Debugging for integration
// 09-NOV-1998 smg Added automatic version header
// 15-NOV-1998 Orim Initial modifications for version 3.0
// 18-NOV-1998 txe Improved exception handling
// 04-DEC-1998 Orim Modifications for release 4.0 (conn., extra methods)
//
////////////////////////////////////////////////////////////////////////////
import java.net.URL;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
public class ClientRMI
implements ClientRMIIface, java.io.Serializable
{
// Class variable declarations
private static final String DEFAULT_IP = "mamba.cs.virginia.edu";
private static final String DEFAULT_PORT = "1202";
private static final String DEFAULT_RMI_NAME= "ServerRMI";
private String server_ip_port;
private String server_rmi_name;
private int my_id;
private int my_password;
private static final int FAILED = 0;
private ServerRMItoClientIface server_iface = null;
private ClientEngine my_engine = null;
///////////////////////////////////////////////////////////////////
//
// ClientRMI Constructor - the client automatically exports itself.
//
///////////////////////////////////////////////////////////////////
public ClientRMI (ClientEngine engine)
throws NullException, Exception {
my_engine = engine;
if (engine == null) {
throw new NullException ("engine");
}
// export the RMIClient as a remote object
Print("Exporting Object");
UnicastRemoteObject.exportObject(this);
}
///////////////////////////////////////////////////////////////////
//
// Connect - invoked by ClientEngine. It finds the server
// on a specified port, and gets the initial map out of it.
//
///////////////////////////////////////////////////////////////////
public Map Connect (String ip, String port)
throws RemoteException, Exception {
// Get port/host/name information off of the web page
String temp_ip, temp_port;
if (ip == null) {
temp_ip = DEFAULT_IP;
}
else {
temp_ip = ip;
}
if (port == null) {
temp_port = DEFAULT_PORT;
}
else {
temp_port = port;
}
server_rmi_name = temp_ip + ":" + temp_port;
// Look up the server port/service and get the initial map
String server_name = "//" + server_rmi_name + "/" + DEFAULT_RMI_NAME;
Print("Server Lookup for '" + server_name + "'");
server_iface = (ServerRMItoClientIface)Naming.lookup(server_name);
return (server_iface.ConnectClient());
}
///////////////////////////////////////////////////////////////////
//
// SetClientID - invoked by ClientEngine. It asks the server
// whether it can get a specific module.
//
///////////////////////////////////////////////////////////////////
public boolean SetClientID (int module_num)
throws RemoteException, Exception {
int result = server_iface.RegisterClient (module_num, this);
if (result != FAILED) {
my_id = module_num;
my_password = result;
return (true);
}
else {
return (false);
}
}
///////////////////////////////////////////////////////////////////
//
// Quit - invoked by ClientEngine. It is the only notification of
// this event to the server.
//
///////////////////////////////////////////////////////////////////
public void Quit ()
throws Exception {
server_iface.ClientQuit(my_id, my_password);
}
///////////////////////////////////////////////////////////////////
//
// ReceiveMap - implementation of ClientRMIIface. It gets the Map
// object passed to it, and it simply hands it along to the
// ClientEngine.
//
///////////////////////////////////////////////////////////////////
public void ReceiveMap (Map m)
throws RemoteException, Exception {
try {
my_engine.ReceiveMap(m, my_id);
}
catch (Exception e) {
my_engine.Error(e);
throw (e);
}
}
///////////////////////////////////////////////////////////////////
//
// ReceiveStats - implementation of ClientRMIIface. It gets the Stats
// object passed to it, and it simply hands it along to the
// ClientEngine.
//
///////////////////////////////////////////////////////////////////
public void ReceiveStats (Stats stats)
throws RemoteException, Exception {
try {
my_engine.ReceiveStats(stats, my_id);
}
catch (Exception e) {
my_engine.Error(e);
throw (e);
}
}
///////////////////////////////////////////////////////////////////
//
// SendChanges - invoked by ClientEngine. It gets the Module
// belonging to this client, and passes it to ServerRMI.
//
///////////////////////////////////////////////////////////////////
public void SendChanges(Module m)
throws Exception {
try {
server_iface.ReceiveModule(m, my_id);
}
catch (Exception e) {
my_engine.Error(e);
throw (e);
}
}
///////////////////////////////////////////////////////////////////
//
// Shutdown - implementation of ClientRMIIface. It simply tells
// the ClientEngine it's no longer needed.
//
///////////////////////////////////////////////////////////////////
public void Shutdown ()
throws RemoteException, Exception {
my_engine.Shutdown();
}
///////////////////////////////////////////////////////////////////
//
// Print - ClientRMI's own method, receiving a string from within
// ClientRMI, and in turn hands it off to ClientEngine for display.
//
///////////////////////////////////////////////////////////////////
private void Print(String s) {
my_engine.PrintMessage("RMI: "+s);
}
}
////////////////////////////////////////////////////////////////////////////