RPC

RPC is a very simple example of the CommonPoint(TM) application system's RPC mechanism. It shows how to implement a simple caller-dispatcher pair. It is intended to be used as an RPC template, in which you should be able to change the class names and put in your own functions fairly easily.

Files and classes

AdditionDispatcherMain.C

This file shows how to set up and run a dispatcher.

The TQualityOfService object that is passed into the constructor of the TStandardServiceDefinition object determines whether or not the service is accessible to programs on remote machines. This example only allows for local access, not remote.

Users of TServiceDefinition must take care to properly increment the reference count after creating it. TServiceDefinition will delete itself when the reference count goes to zero, so you should not delete it yourself.

TDispatcherThread is used to launch the dispatcher. This starts another thread which does the dispatching. For another way to start a dispatcher, look at the TemplateRPC sample.

AdditionCallerMain.C

This file shows how to create a service reference. In the future, developers will not typically create service references, they will receive references from the network browser.

It creates a caller and makes remote calls with it.

The try-catch block demonstrates that if an exception is thrown in the dispatcher, it is propagated through the caller.

MRemoteCaller objects have an ExitDispatcher call that shuts down the dispatcher.

It isn't necessary to start the dispatcher if it isn't running because making a remote call cause it to autostart.

AdditionCaller.h

TAdditionCaller::operator= is private because you can't change the transport you are using once it has been set.

The MRemoteCallerDeclarationsMacro is necessary for RPC to work.

TAdditionCaller stores the transport because it creates the transport, and its superclass MRemoteCaller uses the transport but doesn't adopt it, because the transport could be used by another object.

AdditionCaller.C

The MRemoteCallerDefinitionsMacro is necessary for RPC to work.

It is essential that MRemoteCallerEnable is called at the beginning of every constructor.

The only domain-specific member functions are Add and AddOne.

AdditionDispatcher.h

The enum, EAdditionRequest, is used by any MRemoteCaller-derived class that wants to make remote calls to this dispatcher.

The copy constructor and assignment operator are private. Their implementations are exposed to demonstrate that you never copy a dispatcher.

The streaming operators are private. Their implementations are exposed to demonstrate that you can't stream a dispatcher.

The only domain-specific member functions are AddStub and AddOneStub.

AdditionDispatcher.C

The static array of RequestEntry structs in the constructor needs to be there or the dispatcher will never understand requests that are sent to it. The format for each entry is {theItemFromThePublicEnum, aPointerToAFunctionPointer}. The RequestEntry struct tells the dispatcher which function to call when it receives a particular request. {MRemoteCaller::kUnknownRequest} must be the last item in the array.

Note that the stub functions simply call out to the implementation. The dispatcher just dispatches, it doesn't contain any logic. Also note that the TAdditionImplementation object can throw math exceptions, but the dispatcher doesn't do anything because MRemoteDispatcher takes care of any exceptions and propagates them through to the caller.

AdditionImplementation.h

It's just an ordinary streamable object. Nothing special here.

AdditionImplementation.C

This object adds two numbers together, or just adds 1 to a number. It throws an exception of type TMathException if overflow or underflow occurs.

AdditionProtocol.h

This class defines the protocol that the caller and implementation adhere to. It requires that Add and AddOne be overridden by derived classes.

AdditionProtocol.C

Streams the version in and out.

MathException.h

Defines an exception class that has two flavors, kOverFlow and kUnderFlow.

MathException.C

Streams the version in and out.

Notes:

Message streams are used instead of RPC because: they are easier to learn and implement; they can be better for transferring large blocks of data because they have less overhead; and they allow for communicating with legacy servers in future versions of the CommonPoint system.

RPC is used instead of message streams because: RPC takes care of marshalling and unmarshalling parameters; it propagates exceptions from the dispatcher to the caller; and it is more invisible--if done properly RPC can look like regular function calls, rather than obvious remote communication (like message streams).


Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.