EQUIP2 Remote Dataspace Protocol - ActionScript

Chris Greenhalgh, 2007-06-03; last updated 2007-06-03

Introduction

The packate equip2.net defines a protocol-independent remote dataspace access and serving API. In particular, equp2.net.DataspaceServer allows the construction of servers and the their association to particular dataspaces, while equip2.net.RemoteDataspace allows the creation of proxies for remote dataspaces which can be accessed via equip2.net.DataspaceConnection instances obtained from it.

These classes take URLs to specify the protocol to be used to expose/access the dataspace. There are currently two supported protocols:

The equip2:... protocol also allows different forms of marshalling to be specified. The only one supported at present is a text encoding compatible with ECMAScript (including ActionScript), which can be used to access the dataspace from a Flash movie.

Command-line Usage

The standard dataspace server equip2.net.j2se.Server can be used to expose a dataspace via the ActionScript-compatible protocol, e.g. by:
> java equip2.net.j2se.Server equip2:socket://:9123 ds1 memory
Note the DataspaceServer URL which specifies the EQUIP2 remote protocol, using a TCP (server) socket on port 9123. The dataspace name is specified as 'ds1' and of type 'memory' (i.e. transient).

As a test example, the tutorial application equip2.net.test.j2se.RemoteDataspaceTupleTest can be used to share mouse clicks via such as dataspace, e.g. by:

> java equip2.net.test.j2se.RemoteDataspaceTupleTest \
equip2:socket://localhost:9123;protocol=text/x-actionscript ds1 p1
Note the RemoteDataspace URL which specifies the EQUIP2 remote protocol, using a TCP (client) socket connecting to the local machine, port 9123, and using the specific marshalling (protocol=...) 'text/x-actionscript', which is implemented by the equip2.core.marshall.impl.ECMAScriptMarshaller and ECMAScriptUnmarshaller classes.

Remote Dataspace Protocol

The protocol begin by the client sending an ASCII encoding text line (ending with '\n') to the server identifying the encoding to the be used. Currently (internally) defined MIME types which can be specified are:

The server responds with a single similar line identifying the protocol that will be used. In principle this might be different from that suggested by the client.

Subsequent interaction is remote method invocations initiated by the client, each with a single response. Each request is encoded as an instance of class equip2.core.marshall.MethodCallRequest (which is generated from etc/equip2.core.marshall.MethodCallRequest.xml by the Simple_Bean_Generator). Each request generates a single response which is an instance of class equip2.core.marshall.MethodCallResponse (which is generated from etc/equip2.core.marshall.MethodCallReply.xml similarly).

The properties of MethodCallRequest are:

The properties of MethodCallReply are:
The remote interface is defined by the Java interface equip2.net.equip2.IRemoteDataspace which is generated from etc/equip2.net.equip2.IRemoteDataspace.xml by XLST transformation specifically for remote interface generation (avoid the need for language reflection). The remote interface is:
package equip2.net.equip2;
/** Remote Dataspace RPC interface
* Autogenerated by interface2javainterface.xsl */
public interface IRemoteDataspace {

/** announce/register a new client. */
java.lang.String newClient( java.lang.String dataspaceName )
throws equip2.net.DataspaceNotFoundException, equip2.rpc.RpcException;

/** IDataspaceSession core method - match. */
java.lang.Object[] sessionMatch( java.lang.String sessionName, java.lang.Object template, boolean readOnly )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method - match. */
int sessionCountReadonly( java.lang.String sessionName, java.lang.Object template )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method - match. */
java.lang.Object sessionGet( java.lang.String sessionName, java.lang.String classname, java.lang.Object identity )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method. */
void sessionBegin( java.lang.String sessionName, int sessionType )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method. */
void sessionEnd( java.lang.String sessionName, equip2.core.impl.SessionManagedObject[] changedObjects )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method. */
void sessionAbort( java.lang.String sessionName )
throws equip2.rpc.RpcException;

/** concrete implementation of addlistener */
void doAddChangeListener( java.lang.String localListenerId )
throws equip2.rpc.RpcException;

/** IDataspaceSession core method. */
void doAddObjectsListener( java.lang.String localListenerId, java.lang.Object templateValue, int realChangeMask )
throws equip2.rpc.RpcException;

/** concrete implementation of removeistener. */
void doRemoveListener( java.lang.String localListenerId )
throws equip2.rpc.RpcException;

/** concrete implementation of islistener */
boolean doIsListener( java.lang.String localListenerId )
throws equip2.rpc.RpcException;

/** get callback information for listeners. */
equip2.net.equip2.RemoteDataspaceEvent[] pollListeners( )
throws equip2.rpc.RpcException;
}

This API corresponds directly to the dataspace internal interface equip2.core.impl.IDataspaceSession and the listener interface equip2.core.IEventManagement (except that Strings are used in some cases rather than local/unmarshallable objects, such as sessions).

A new client MUST perform a newClient request first to identify the dataspace which it wishes to access. This will fail if the connected server has not been registered with a dataspace of that name.

As usual, listener operation should be performed OUTSIDE a session, whereas other operations must be bracketed by sessionBegin/sessionEnd calls. NOTE: At present a single connection cannot support multiple concurrent sessions.

Refer to EQUIP2_Introduction.html for general descriptions of the API operations. Changes are described by suitably configured instances of class equip2.core.impl.SessionManagedObject (which are generated internally by the normal dataspace session objects and the DataspaceConnection object(s)).

ECMAScript Marshalling

The ECMAScript marshalling uses the following mappings (Java <-> ECMAScript):

See below for examples. Note that equip2.core.objectsupport.impl.Coerce.coerce(Object value, String classname) will perform most of the corrective coercions that arise from the asymetry of this transformation, e.g. cast long to int or short as required. This is used in the auto-generated bean helpers and remote interface stubs.

For compatibility with the Flash XMLSocket a '0' byte is marshalled after every request or response object, however it is not required, so for testing can be omitted.

Sample messages and responses

Initial protocol proposal from client:
text/x-actionscript[newline] 
Acceptance response from server:
text/x-actionscript[newline] 

Announcing a new client and requesting use of dataspace 'ds1' (do not include new lines):

{_classname:"equip2.core.marshall.MethodCallRequest",
method:"newClient",arguments:["ds1"]}

Note the marshalling of an instance of class equip2.core.marshall.MethodCallRequest as an ActionScript object with the property _classname as the name of the corresponding Java class.

Success response:

{_classname:"equip2.core.marshall.MethodCallReply",
successful:true,value:"client1"}

Client request to begin a session (session identified 's1', type read/write - ISession.READ_WRITE=1):

{_classname:"equip2.core.marshall.MethodCallRequest",
method:"sessionBegin",arguments:["s1",1],}

Client request to match any in that session (session 's1', null template, readonly = false):

{_classname:"equip2.core.marshall.MethodCallRequest",
method:"sessionMatch",arguments:["s1",null,false]}

Example success response:

{_classname:"equip2.core.marshall.MethodCallReply",
successful:true,value:[{_classname:"equip2.net.test.MyDataType",name:"p1",x:14,y:26}]}

Client request to end session with no changes:

{_classname:"equip2.core.marshall.MethodCallRequest",
method:"sessionEnd",arguments:["s1"]}

Change Log

2007-06-03