3.4 RMI for C++

Zeus-Framework implements a remote object invocation RMI for C++. RMI is basically used to put logic components to some distant system. Instead of communicating using a raw socket interface and byte stream, RMI provides a comfortable API to the programmer. He hasn't to care about sockets and protocols. Instead he can call the remote object over an C++ interface not knowing where the remote object is located.

To do that Zeus-Framework implements a well known pattern of RMI, the Skeleton-Stub-Pattern. The Stub is used by the client to receive the method call and to stream the data into a byte stream. This process is called marshalling. The Skeleton does exactly the inverse part. It takes a byte stream (from a socket interface) and rebuilts the real method call. This is called unmarshalling. At the end the Skeleton calls the method of the servant object (real object). The return values are now marshalled by the Skeleton and sent back to the Sub.

RMI includes following components

  • [rmicc]: Generates skeletons and stub-files out of a remote interface definition
  • Naming Service: Naming service to register and lookup remote objects
  • NameServer: Naming server for global object registration.
  • Classes: Classes for remote object development.

3.4.2 Parameter types

The method calls of RMI accepts primitive data types, serializable objects and other remote objects as parameters. The serializable objects must implement the interface ISerializable, where as the remote objects has to implement IRemoteObject interface. The difference between those to parameter types is that serializing an object creates a copy of the original object. On the otherside the using remote object as a parameter will submit only a remote reference. The reference contains:

  • Address: IP address of the servant.
  • Port: Port address of the servant socket.
  • ClassName: Name of the servant class
  • CodeModule: Name of the code module (package)

Using remote object as parameter will create automaticaly a Stub on the receiver side, witch will connect to the servant object. In this case no name server is needed.

3.4.3 [rmicc]: File generator

rmicc [Options] [File]

The tool [rmicc] is needed to generate skeleton and stub-files. It takes a remote interface definition as input (see above).

  • Input: remote interface definition (ex. IMessagePool.hpp)

  • Output:

    Skeleton class (ex. MessagePool_Skel.h and MessagePool_Skel.cpp)

    Stub class (ex. MessagePool_Stub.h and MessagePool_Stub.cpp)

The servant class must be implemented manualy. [rmicc] does not generate any pre implementations yet. The following list shows the options of [rmicc]:

--check-only Checks the remote interface definition file only. No skeletons and stubs are generated.
--output=path Output path of the generated skeletons and stub files
--iinclude=path Include path for remote interface file. This path is added as #include<[path][interfacefile]>
--stubinclude=path Include path for stub file
--skelinclude=path Include path for skeleton file
--interfaces=list Adds a list of known remote interfaces interfaces.
--help print the help

Examples of use:

> rmicc --check-only ./IMessagePool.hpp
> rmicc ./IMessagePool.hpp
> rmicc --iinclude=zeusbase/Messaging/Interfaces/ ./IMessagePool.hpp

The [rmicc] is included in Zeus-Framework and will be built automatically when building the framework.

3.4.4 Naming Service

The naming service is used to register remote objects. The naming service returns the remote object by name. Objects might be grouped by catagories as well. The service can run locally or can connect to a nameserver (see below).

The naming service is implemented using the singleton object Naming.

#include <zeusbase/Remote/Naming.h>
#include "IRemoteTestObject.hpp"
  //Connect to naming server
  Naming.connect(L"", 7000);
  //Lookup for remote object
  TAutoPtr<IRemoteObject> pRemoteObject = NULL;
  if (Naming.lookup(TString(L"MyObject"), pRemoteObject) == RET_NOERROR)

3.4.5 NameServer

Instead of using the naming service locally it can connect to a remote server called nameserver. The nameserver is used to register remote objects inside a network area. Client applications can lookup objects using the corresponding object name.

The nameserver of Zeus-Framework is installed automatically. It need the configuration file nameserver.properties for binding address and port configuration.


Before starting your application providing a remote object, the nameserver needs to be started. Run following command:

> nameserver

Running the nameserver with different IP address or port

> nameserver server.Address=

The naming service (Singleton) needs to be connected to the nameserver using Naming.connect(L"", 7278);. Now the remote object can be bound to the service.

See the RMI example for details.

3.4.6 Classes

The Zeus-Framework provides several abstract classes used for RMI.

  • TAbstractRemoteObject: Implements the abstract servant object. All servants must inherit from this class.
  • TAbstractSkel: Implements the abstract skeleton and its base functionality.
  • TAbstractStub: Implements the abstract stub.

The method calls between a stub and the servant object are typically synchronous. With Zeus-Framework 2.x the RMI is also able to handle asynchronous calls. Use the ASYNCH_MQUALIFIER instead of MQUALIFIER.