Exchanging Messages

Sending a message to a wellknown cell

To exchange messages, you need A typical codelet to send an argument list to a server cell ( let's say 'anyServer' ) would look like :
   CellPath path = new CellPath( "anyServer" ) ;
   
   Object [] argList = new Object[3] ;
   
   argList[0] = "set-request" ;
   argList[1] = "timeout" ;
   argList[2] = new Integer(2000) ;
   
   CellMessage message = new CellMessage( path , argList ) ;
   try{
      sendMessage( message ) ;
      say( "Message ID : "+message.getUOID() ) ;
   }catch( Exception e ){
      esay( "Got an exception : "+e ) ;
   }
The CellPath 'path' is generated and the message object 'argList'. Both is combined to create the CellMessage. The CellMessage is send by sendMessage. There are mainly two types of exceptions which can occure. After the call to sendMessage the 'message' object contains an UnifiedObjectIdentifier dmg.cells.nucleus.UOID. This UOID can be used to identify the answer which may expected from the server.

Receiving Messages

The CellAdapter provides a member function with needs to be overwritten to receive messages :
messageArrived( CellMessage message )
The messageArrived method is called in a seprarated thread. The argument is the dmg.cells.nucleus.CellMessage . The CellMessage can be inspected to get the source path and the message object.
public void messageArrived( CellMessage message ){

   CellPath  sourcePath = message.getSourcePath() ;
   Object    obj        = message.getMessageObject() ;
   Object [] array      = (Object []) obj ;
   String    reqType    = (String) array[0] ;
   say( "Request received from : "+sourcePath ) ;
   say( "Request type          : "+reqType ) ;

}

Replying a message

In most cases, a server cell is not interested in the source of a request it has to process. So the CellMessage provides mechanisms to easily return the answer to the sender. Extending the example from above, the message object might by changed.
   array[0] = "set-answer" ;
   array[1] = "O.K." ;
   arrry[2] = null ;
Because the message.getMessageObject() returns a reference to the original message ( and not a copy ) a modification of array changes the object which we need to send back.

The message.setMessageObject method allows to reply a totally different object.

   Vector vec = new Vector() ;
   vec.add( "set-answer" ) ;
   vec.add( "O.K." ) ;
   message.setMessageObject( vec ) ; 
To actually send the message back, the direction has to be reverted first.
   message.revertDirection() ;
   
   try{
   
      sendMessage( message ) ;
      
      say( "Message ID : "+message.getUOID() ) ;
   }catch( Exception e ){
      esay( "Got an exception : "+e ) ;
   }

    
}
A new UOID is assigned to the message, but the original UOID can be obtained by the new destination, the former source, by calling the message.getLastUOID() method.

Examples

The XchangeMessage.java example can be started as client or as server, depending on the number of arguments. Without arguments it's a server. Providing one or more arguments lets it become a client. The first argument is the destination, which is the name of the serverCell and the second, optional argument is the number of seconds between two requests. In addition the example code shows how to use arguments when starting a cell. Copy the code into a file named XchangeMessage.java, compile it and run it within the standard domain as described in My First Cell. Log into the domain and start a server and two clients.
create XchangeMessage pingServer
create XchangeMessage clientA   pingServer
create XchangeMesssge clientB  "pingServer  4"
Try to find out what happens if you kill the PingServer.

Because a client is as well a server, you may create a chain of ping cells.

create XchangeMessage serverOnly
create XchangeMessage clientServer  serverOnly
create XchangeMessage clientOnly    clientServer