server
Class Server

java.lang.Object
  extended by java.rmi.server.RemoteObject
      extended by java.rmi.server.RemoteServer
          extended by java.rmi.server.UnicastRemoteObject
              extended by server.Server
All Implemented Interfaces:
java.io.Serializable, java.rmi.Remote, ServerInterface

public class Server
extends java.rmi.server.UnicastRemoteObject
implements ServerInterface

Class Server is a simple illustration of a remote server that uses RMI communication. The server provides three typical methods to a client: receiveClientInput, compute, and getServerOutput. These methods are described further in their respective method documentation.

The main method of the server accepts two command-line arguments. The first argument is the name of the host computer on which the server runs. The hostname may be suffixed with a colon-delimited port number. If the port number is not present, the rmiregistry on the host is assumed to be running on the well-known port 1099. So, e.g., a legal hostname could be "waldorf.csc.calpoly.edu" or "waldorf.csc.calpoly.edu:1098", the latter selecting alternate registry port 1098.

The second command-line argument is an optional flag indicating if the server's GUI should be displayed when it runs. If the argument is missing, the default behavior is to display the GUI. If the second argument is "-nd", then no GUI display is shown. Using the "-nd" argument is useful when the server is run in a context where there is no support for a Java GUI display, for example, running the server on a UNIX machine like waldorf when logged into waldorf via telnet from a Windows PC.

See the example Client class for a description of how a client connects to this server and uses its services.

It is noteworthy in this example that all method calls are initiated from the client. I.e., the computation is 100% client-driven. The server calls no client methods. Specifically, input data are pushed from the client to the server by the client's call to receiveClientInput. The server computation is initiated by the client's call to compute. And then the output data are pulled by the client from the server with the client's call to getServerOutput.

This client-driven computation could be replaced with a server-driven form, where the server calls client's methods. Or there could be some combined form, e.g., the client performs a push of its input data, and the server responds with a push its output. Whether to use a client- or sever-driven form of computation depends on a number of factors, including where the end-user fits into the computation, which side should perform input data validity checking, and what security concerns there are. Details of these issues are beyond the scope of this example.

See Also:
Serialized Form

Field Summary
protected  ClientDataInterface clientData
          Local copy of client input for computing with
protected static boolean displayOn
          True if the display is on, i.e., the 2nd command-line arg != "-nd"
protected  int serverOutput
          Value computed by the server
protected static javax.swing.JTextField textField
          The text field that displays the received client data; received client data are printed to stdout instead of this text field if the GUI display is not active
 
Fields inherited from class java.rmi.server.RemoteObject
ref
 
Constructor Summary
Server()
          Construct this by calling the parent constructor.
 
Method Summary
 void compute()
          Perform some computation using the client input.
 java.lang.Object getServerOutput()
          Return computation results back to the client, when the client calls for it.
static void main(java.lang.String[] args)
          Get the hostname from the command-line argument, exiting if there is none.
 void receiveClientInput(ClientDataInterface clientData)
          Receive some input from the client.
protected static void setupDisplay(java.lang.String hostname)
          Set up the display as a JFrame with a labeled text field.
protected static void setupServer(java.lang.String hostname)
          Perform the necessary setup for remote execution.
 
Methods inherited from class java.rmi.server.UnicastRemoteObject
clone, exportObject, exportObject, exportObject, unexportObject
 
Methods inherited from class java.rmi.server.RemoteServer
getClientHost, getLog, setLog
 
Methods inherited from class java.rmi.server.RemoteObject
equals, getRef, hashCode, toString, toStub
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

clientData

protected ClientDataInterface clientData
Local copy of client input for computing with


serverOutput

protected int serverOutput
Value computed by the server


textField

protected static javax.swing.JTextField textField
The text field that displays the received client data; received client data are printed to stdout instead of this text field if the GUI display is not active


displayOn

protected static boolean displayOn
True if the display is on, i.e., the 2nd command-line arg != "-nd"

Constructor Detail

Server

public Server()
       throws java.rmi.RemoteException
Construct this by calling the parent constructor.

Throws:
java.rmi.RemoteException
Method Detail

receiveClientInput

public void receiveClientInput(ClientDataInterface clientData)
                        throws java.rmi.RemoteException
Receive some input from the client. Store a local copy for computation use. Also, display the data in the server's display window, or output the data to stdout if no display is available.

Specified by:
receiveClientInput in interface ServerInterface
Throws:
java.rmi.RemoteException

compute

public void compute()
             throws java.rmi.RemoteException
Perform some computation using the client input. In this case, we simply add 1 to the numeric input value received by the receiveClientInput method.

Specified by:
compute in interface ServerInterface
Throws:
java.rmi.RemoteException

getServerOutput

public java.lang.Object getServerOutput()
                                 throws java.rmi.RemoteException
Return computation results back to the client, when the client calls for it.

Specified by:
getServerOutput in interface ServerInterface
Throws:
java.rmi.RemoteException

setupDisplay

protected static void setupDisplay(java.lang.String hostname)
Set up the display as a JFrame with a labeled text field. The hostname input is the command-line argument from main.


setupServer

protected static void setupServer(java.lang.String hostname)
Perform the necessary setup for remote execution. The hostname input is a server name with optional port number, e.g., "waldorf.csc.calpoly.edu" or "waldorf.csc.calpoly.edu:1098". Server setup entails the following processing:

  1. Set up a Java security manager if there isn't one already running on the server machine.

  2. Create a server name with the syntax "//hostname/Server". The "//" prefix is required by the Naming.rebind method. The hostname is the given string argument. The "/Server" suffix is the name of the server class, i.e., this class.

  3. Allocate a remote server instance and bind it in the host's rmi registry. This makes the server available to requesting clients.

  4. Handle any exception that may occur during server binding. The most typical problems include that the server is not running or that the security policy is not met. The easiest way to avoid security policy problems is to use the most liberal policy possible (see the file ./java.policy.liberal).


main

public static void main(java.lang.String[] args)
Get the hostname from the command-line argument, exiting if there is none. Then call the display and server setup methods and we're ready to accept client requests.