Personal tools
You are here: Home / cmgui / Wiki / Remote Procedure Call Systems
Log in

Forgot your password?

Remote Procedure Call Systems

<h1>Remote procedure calls in CMISS</h1> <h2>General background</h2> Remote procedure calls(RPC) allow calls to methods across process boundaries. The two processes may be on different machines, or they may be on the same machine.

In the context of CMISS, there are a number of reasons for supporting remote procedure calls. Examples are:

  • Communicating between the CMISS backend and CMGUI. The worm-hole is an example of a non-standard RPC method.
  • Communicating between CMGUI and applications which embed cmgui(across process boundaries). For example, cmgui_server(a non-standard RPC implementation) and cmgui_corba_bridge(using the standardised protocol CORBA) have been used by mozCellML to use it to draw graphs in cmgui from another process.
  • Integrating different backends or cmgui processes running on different machines so they can be utilised by a process on a different machine(for example, a client running on the desktop system of an end-user could make calls to one or more processes already running on a HPC, across a standard interface).
  • Collaborating between groups. An externally accessible object could persist on a server, and other research groups could could methods on that object. This could allow parts of CMISS that are closed source to be used outside the institute without giving away either binaries or source, but instead by sharing a file describing the interface. It could also be used to allow research groups to call methods on objects that require the use of large amounts of data that other groups may not be able to store.

Methods for providing remote procedure calls generally include:

  • A protocol for communicating calls.
  • A way to serialise calls at the clientin response to a method call by the application using the RPC method.
  • A way to deserialise calls at the server, map these into calls within some language binding, and return a response.

Some, but not all, method include:

  • A way to describe the interface exposed.
  • A way to associate calls with objects.
  • A way to communicate specific objects and access them later.
  • A way to pass objects around 3 or more parties and still preserve knowledge of how to make calls on that object(i.e. including an IP address or other transport address).


The mozCmgui extension and the Physiome CellML Environment are using XPCom and

<h2>CORBA</h2> CORBA is an acronym for the "Common Object Request Broker Architecture". It is defined by the "OMG(object management group)", . OMG does not provide an actual code, only the specification.

Interfaces are defined in a language called IDL(interface description language). The specific variant of IDL used is called OMG IDL. The IDL format is defined in the main CORBA specification for any particular version of CORBA.

A sample of an IDL from cmgui_corba_bridge(this code is experimental, but functional, and exact details are subject to change. Consider this example as illustrative only): <pre> module CMGUIAPI {

interface Node;

interface Element : XPCOM::IObject {

  • Sets the node corresponding to a certain index of this element.
  • @param nodeIndex The index at which to set the node.
  • @param n The node.


void setNode(in unsigned long nodeIndex, in Node n) raises(CmguiError);


#pragma ID Element "DCE:d441d657-de33-43ce-9de6-51eac8ccc89f:1" }; #pragma flat_prefix Cmgui </pre>

When using CORBA, you need to use an ORB(object request broker). The ORB is provided by a third-party vendor(i.e. not OMG, and we probably wouldn't write our own ORB). The "OMG CORBA downloads page", provides a list of some free-to-download ORBs, and there are many more commercial ones. There are high quality ORB implementations, such as omniORB, available under the GPL.

CORBA defines language mappings, i.e. specific details of what CORBA provides, for Ada, C, C++, COBOL, Java, Lisp, PL/1, Python, and Smalltalk, as well as for a CORBA specific scripting language called IDLscript. Aside from the headers included and the ORB libraries linked in, if an application(client or server) is written in a CORBA compliant fashion, no changes are required to change from one ORB to another. For languages which do not define a language mapping(for example perl), individual ORB vendors choose how to map CORBA to that language(and different vendors) may do so differently.

A CORBA compliant ORB provides every interface required of it by the CORBA specification, and it does so in compliance with the language mapping. A CORBA compliant application does not use any ORB specific interfaces, and so only interacts with the ORB in ways defined in the CORBA specification. Therefore, a CORBA compliant application can switch ORBs without code changes, aside from changing the ORB headers included, and the compile/link time flags(e.g. linking to the ORB libraries). However, this may not be so simple for perl and other languages with no standard language mappings.

In addition to the interface(defined in IDL), there must also be an implementation of the calls defined in the somewhere. The specific implementation is referred to as the "servant". A servant can be associated with one or more "objects". Objects can be referred to globally via an "object reference". Objects can be configured to outlive the servants, and so persist for an arbitrary length of time(i.e. even if the application is restarted).

In CORBA, all remote calls must be made on an object reference(as in, for example, Java). It is not possible to define static methods. However, you could just define a single big interface with lots of operations(the equivalent of method calls in C++) available on them.

ORBs communicate with each other using a general protocol known as the GIOP(generalised inter-ORB protocol). On a TCP/IP network, they use a specific instance of GIOP called IIOP(Internet inter-ORB protocol). Hence, two different ORBs can still communicate with each other. If an ORB is communicating with another ORB of the same kind, it is allowed to use a different, more efficient protocol. An example would be when a call is being made within the same process, where an ORB might avoid doing the serialisation and deserialisation altogether.

Object references are portably described as IORs(interoperable object references). IORs can be passed between ORBs and still work(for example, when using IIOP, an IOR includes an IP address). IORs can be stringified(e.g. IOR:010000001d00000049444c3a6f6d672e6f72672f434f5242412f4f626a6563743a312e300000000001 000000000000006c00000001010200100000003133302e3231362e3230382e31333500fa80000011000000 ff5850434f4dfe6f195a4201000b2300020000000200000000000000080000000100000000545441010000 001c00000001000000010001000100000001000105090101000100000009010100 ) or in a special URL format, and passed to another application via a non-CORBA means. This is useful for getting the first object used to create other objects.

CORBA is well adopted, see "", for a page with "CORBA success stories".

The CORBA specifications define a bridge between DCOM and CORBA. There is a software package called "", XPCORBA which bridges from Mozilla XPCOM to CORBA. There is a two way SOAP-to-CORBA bridge available at "",

<h2>XML/RPC</h2> XML/RPC(Extensible markup language remote procedure call) describes a way of serialising remote procedure calls and their responses into XML. It is defined at "", by a software company called UserLand software.

It is a very simple(and easy to implement) protocol. It does not provide a way to define interfaces. It does not have the native concept of objects or object references. It does not provide any enforcement of type-safety at the specification level.

An example of an XML/RPC call: <pre> &lt;?xml version="1.0"?> &lt;methodCall>

&lt;methodName>fooBar&lt;/methodName> &lt;params>


&lt;/param> &lt;param>

&lt;value>&lt;string>Hello World&lt;/string>&lt;/value>



&lt;/methodCall> </pre>

See "", for a long list of implementations. Each implementation will be different to use, as XML/RPC does not define an API or any language mappings, but instead leaves this to individual applications. It would also be simple to write our own language mapping. However, each call does require more work, since there is not necessarily any automatic generation of stubs and the like. <h2>SOAP</h2> SOAP(which used to be an acronym for Simple Object Access Protocol, but now is not according to the W3C), is defined by the "W3C(World Wide Web Consortium)", . It is more complicated to use than XML/RPC, and allows for new features like structured data types.

From the W3C SOAP primer: "SOAP is fundamentally a stateless, one-way message exchange paradigm, but applications can create more complex interaction patterns (e.g., request/response, request/multiple responses, etc.) by combining such one-way exchanges with features provided by an underlying protocol and/or application-specific information. SOAP is silent on the semantics of any application-specific data it conveys, as it is on issues such as the routing of SOAP messages, reliable data transfer, firewall traversal, etc. However, SOAP provides the framework by which application-specific information may be conveyed in an extensible manner. Also, SOAP provides a full description of the required actions taken by a SOAP node on receiving a SOAP message."

Like XML/RPC, SOAP is a protocol and does not specify a set of API calls, nor a language binding for those calls. Hence, each implementation will be distinct.

Unlike XML/RPC, it does have the "Web Services Description Language", WSDL, which describes the interfaces available in an XML form.

There are SOAP implementations available for C++ and Java, "Apache Axis", as well as some for C, PHP, and Perl, and "Python", <h2>OLE/DCOM/COM/.NET</h2> These technologies are defined by "Microsoft",, and work mainly on the Windows operating system product.

Mono documentation states that support for this is "to be added", so using these technologies would tie us to Microsoft Windows. <h2>DCOP</h2> "DCOP", is a standard defined by the KDE developers, which allows communication between different KDE components.

It defines a C and C++ binding, and an IDL variant called dcopidl. Communication is via the X11 server(i.e. this would not work on platforms which do not use X11).

There is a DCOP-XML/RPC bridge available. <h2>Java RMI</h2> The Java RMI(Java remote method invocation) is a protocol allowing remote procedure calls between Java processes which may be running on different systems. It completely specifies the protocol and the Java language binding. It cannot be used to interoperate with non-Java code.

Interfaces are defined in Java using the standard way of defining interfaces in Java, and these interfaces extend from the java.rmi.remote marker interface to indicate that the interface can be called remotely. <h2>Sun RPC</h2> This is the oldest protocol described. Like SOAP and XML/RPC it has no inherent object-orientedness, and it is difficult to reference objects without inventing a new scheme.

Sun RPC, or just "RPC", is defined by "RFC1057", . Although the specification describes the protocol only, RPC libraries following a common API are available on most *nix variants.

This protocol underlies NFSv4, as well as a number of other applications.

Interfaces are described in a format called XDR. Programs like rpcgen can produce stubs and skeletons given an XDR file. <h2>Custom implementation</h2> The possibility remains to invent our own protocol, and define it however we want. This may involve writing a compiler to generate stubs and skeletons to perform all the work.

<h2>RakNet</h2> (From Glenn) In my day job I have been using a network library called "RakNet:". It provides a very simple RPC mechanism, which is aimed at games but might be useful here. It's RPC mechanism allows you to define and call a named remote procedure on a connected peer. It uses UDP and implements a reliability layer on top of that. The advantage is that it's very efficient (1 byte overhead per RPC call, limit 255 defined RPCs) but the tradeoff is that the function signature of the remote procedure always has to be the same. You get passed a pointer to a struct that contains the sender, an input buffer (which you can cast to a struct) and a couple of other things. For a game this relieves you from encoding and decoding a packet ID and makes things a bit easier to manage. Not sure how relevant it would be for CMISS but thought it worth mentioning.