|
|
|
|
|
|
- Usage
- No need to derive from Remoting interfaces (like CORBA, RDMI)
or explicit signatures (with Remoting excpetions).
- No IDL needed, but working directly with reflection information.
- Every interface/class can be invoked by RDMI.
- Support of in, out, inout, byref and byval.
- Weak invocation doesn't need the type information on the client
if something is wrong with arguments, the server will respond with exception.
out, inout parameters are not available for weak invocation.
Weak invocation uses a opaque Object as client object.
- Strong invocation uses type information to map in, out, byval byref
to parameter set.
Remote references can be casted to native Interfaces. Client and Server
code doesn't make difference between remote and local objects.
- The weak and strong uses the standard DMI mechanism with New, invoke,
static_invoke, peek, poke, static_peek, static_poke.
- Selection, if parameter are tranfered by value or by (remote-) reference
can be declared by the the parameter attributes of the interface definition.
- If no interface definition is available, Throwable, Strings, Serializables and basic
types are transfered by value, all others by reference.
- 3 ways to identify how to transfer arguments:
- implicit by type of parameter
- by declaration of interfaces.
- by using byRef(), byVal() operators in client code.
- Thrown Exception are transfered transparent from client to server.
- Remote class loading is not possible for native C++ classes.
In a later version interfaces and classes maybe transfered CfgScript.
- Protocol
- Multiple transport and protocol possible, like
binary over TCP, HTTP/XML, etc.
- Using standard reference based GC (no need for explicit calls
to dispose objects).
- Standard references lifes as long a connection lifes.
This has to be emulated in connectionless transports like HTTP.
- Objects independed from connection may be allocated.
- No need for nameservices.
- A client is also a server, which enables callback scenarios.
- Security: In the first version RDMI is only designed to run
on trusted environmnet, mostly running even on the same platform.
The RDMIServer and RDMIClient should provide a simple remote DMI call interface
on TCP/IP basis.
All interfaces with DmiProxy available are handled transparent.
RRdmiClient client = new RdmiClient("localhost:1111");
RMyInterface iface = (RMyInterface)client->New("my.Class", MyInterface::getClass(), arg1);
RMyObject = iface->myFunction(arg1);
RMyOtherInterface mo = new MyOtherClass("asdf");
iface->registerMyListener(mo);
iface->iterThroughtListener(); // remote server may call back client
|
Client/Server impl:
void RdmiServer::call(...)
{
while (true)
{
RDmiRequest req = requestFromCall(...);
RDmiRequest resp = sendReceive(req);
if (resp->isReturnOrEx() == true) // remote call returned immediatelly
{
responseToCall(resp, ...);
return;
}
// recursive back call
RRdmiRequest respresp = resp->handle();
sendReceive(respresp);
}
}
void
RdmiServer::run()
{
while (true)
{
RRdmiRequest req = server->nextRequest();
if (req->isShootdown() == true)
break;
RRdmiRequest resp = req->handle();
server->send(resp);
}
}
|
RDMICall: Header CallOrReturn
Header
Call 0
Return 1
Return
: 0 Return
| 1 Exception
;
returnValue
: ValueOrException
;
Value
: enum RemoteRefId, ClassName
| enum BasicValue TypeChar Value
| enum ObjectValue SerializedObject
;
enum InvokeCmd {
ShootDown,
AddRef,
/**
@param remoteObjectId
@return ReturnValue, int refCount after release
*/
ReleaseRef,
/**
@param ClassName
@param Args
@return ReturnValue
*/
New,
/**
@param remoteObjectId
@param methodName
@param Args
@return ReturnValue
Invoke,
....
}
// server
RRemoteDmiServer server = new RemoteDmiServer(portNo); // listen at port
// client
RRemoteDmiClient client = new RemoteDmiClient(portNo);
RStringBuffer sb = (RStringBuffer)client->New("acdk/lang/StringBuffer", "Hello");
RString s = sb->toString();
|
|
|