Web Socket Bus
General information

Web Socket Bus is used:

On the browser side Web Socket Bus is implemented in webappos.js.

Web Socket URL
ws[s]://[domain_or_ip][:port]/ws/

The web socket connection is as listed above. The trailing slash is essential!

Establishing the connection
OPEN|REOPEN|FROM_TEMPLATE|NEW [login] [token] [app_url_name] [[ack#_for_REOPEN]] [[template_id_for_FROM_TEMPLATE]] [project_id|desired_project_id]

The browser (usually, webappos.js script running there) initiates the web socket connection to activate a web memory slot (or to join an existing web memory slot, e.g., activated by another user).

To activate the web memory slot the browser sends a string message of one of the 4 types listed below.  There must be a single space between every two adjacent parts of the message.  In all cases the [login] argument specifies the current user. The [token] argument is either the connection token received during the login process, or a collaboration token received from another user. The [app_url_name] specifies the application to use to open the given project.

As a response, then the server synchronizes the current memory state (usually, in bulk) until action 0xFF (sync max reference).  After that, the initial action of the underlying web application is called (see initial_action setting in <app.properties>).

On certain circumstances, the server can send some action from the list of Connection management actions (see below).

OPEN
OPEN [login] [token] [app_url_name] [project_id]

Open an existing project [project_id] with the given app.  If some other user has already opened the project, the following conditions have to be met:

A special value "*" for [app_url_name] can be used to indicate that the client wishes to connect to the project that has already been opened by any app. This is useful for debugging purposes.

REOPEN
REOPEN [login] [token] [app_url_name] [ack#] [project_id]

Try to re-open an existing project, for which the connection has been lost.  The [ack#] argument specifies the first action number that is still cached in the browser. Thus, the server can then request to re-sync missing actions. If cached actions are not sufficient for re-sync, the server replies with 0xFA, and the browser must start the connection from scratch by using OPEN.  Currently not implemented. If ack#!=0, sends 0xFA. Otherwise, just opens the project.

FROM_TEMPLATE
FROM_TEMPLATE [login] [token] [app_url_name] [template_id] [desired_project_id]

Creates a new project from the given template. The [template_id] must have one of the following prefixes: "user_template:", "app_template:", "published_template:".

If [template_id] contains spaces, they must be escaped by the backslash as "\ " (the backslash itself cannot be a part of template_id, use ordinary slashes as path separators).  The [desired_project_id] can be slightly modified by appending some integer, if it is already used by existing projects (e.g., created from templates earlier).

NEW
NEW [login] [token] [app_url_name] [desired_project_id]

Bootstraps a new project.  Notice that some web apps specify the initial template, thus, new projects are not actually boostrapped, but created from that initial template.  The project_id can be slightly modified by appending some integer, if it is already used by existing projects. (e.g., bootstrapped earlier).

Syncing one action

An action that does not have a string parameter (non-string-action), is synced as one binary web socket message:

An action that has a string parameter (string-action) is synced as two web socket messages: one binary and one string message.

Actions returning booleans are synchronized only when they succeeded, thus, these boolean return values are not synchronized (assume they are always true).

Class actions
[0x01, rClass], string:"[name]"

Reference createClass (in UnicodeString name)

[0xF1, rClass]

boolean  deleteClass (in Reference rClass)

[0x11, rSubClass, rSuperClass]

boolean createGeneralization (in Reference rSubClass, in Reference rSuperClass)

[0xE1, rSubClass, rSuperClass]

boolean deleteGeneralization (in Reference rSubClass, in Reference rSuperClass)

Object actions
[0x02, rClass, rObject]

Reference createObject (in Reference rClass)

[0xF2, rObject]

boolean deleteObject (in Reference rObject)

[0x12, rObject, rClass]

boolean includeObjectInClass (in Reference rObject, in Reference rClass)

[0xE2, rObject, rClass]

boolean excludeObjectFromClass (in Reference rObject, in Reference rClass)

[0x22, rObject, rToClass]

boolean moveObject (in Reference rObject, in Reference rToClass)

Attribute actions
[0x03, rClass, rPrimitiveType, rAttribute], string:"[name]"

Reference createAttribute (in Reference rClass, in UnicodeString name, in Reference rPrimitiveType)

[0xF3, rAttribute]

boolean deleteAttribute (in Reference rAttribute)

Attribute value actions
[0x04, rObject, rAttribute], string:"[value]/[old-value]" (or string:"[value]", if old value was null)

boolean setAttributeValue (in Reference rObject, in Reference rAttribute, in UnicodeString value)

[0xF4, rObject, rAttribute]

boolean deleteAttributeValue (in Reference rObject, in Reference rAttribute)

[0xA4, rObject, rAttribute], string:"[value]"

validate attribute value (if some collision occurs, the other end point can send setAttributeValue to resolve the collision)

Association actions
[0x05, rSourceClass, rTargetClass, isComposition, rDirectAssociationEnd, rInverseAssociationEnd], string:"[sourceRoleName]/[targetRoleName]"

two references createAssociation (in Reference rSourceClass, in Reference rTargetClass, in UnicodeString sourceRoleName, in UnicodeString targetRoleName, in boolean isComposition)

[0x15, rSourceClass, rTargetClass, targetRoleName, isComposition, rAssociationEnd]

Reference createDirectedAssociation (in Reference rSourceClass, in Reference rTargetClass, in UnicodeString targetRoleName, in boolean isComposition)

[0x25, nAry, associationClass, rAssociationEnd], string:"[name]"

Reference createAdvancedAssociation (in UnicodeString name, in boolean nAry, in boolean associationClass)

[0xF5, rAssociationEnd]

boolean deleteAssociation (in Reference rAssociationEndOrAdvancedAssociation)

Link actions
[0x06, rSourceObject, rTargetObject, rAssociationEnd]

boolean createLink (in Reference rSourceObject, in Reference rTargetObject, in Reference rAssociationEnd)

[0x16, rSourceObject, rTargetObject, rAssociationEnd, targetPosition]

boolean createOrderedLink (in Reference rSourceObject, in Reference rTargetObject, in Reference rAssociationEnd, in long targetPosition)

[0xF6, rSourceObject, rTargetObject, rAssociationEnd]

boolean deleteLink (in Reference rSourceObject, in Reference rTargetObject, in Reference rAssociationEnd)

[0xE6, rSourceObject, rTargetObject, rAssociationEnd]

createLink for already handled event/command (e.g., for informative/debug purposes)

[0xA6, rSourceObject, rTargetObject, rAssociationEnd]

validate the link (if some collision occurs, the other end point can send deleteLink to resolve the collision)

Syncing multiple actions in bulk

Multiple actions are always synced as two web socket messages: one binary and one string message.

Bulk sync action
[0xEE, action1-code, actione1-non-string-arg1, ..., action2-code, action2-non-string-arg1,...], string:"[string-arg]`[another-string-arg]`....`[last-string-arg]"

the format of 2 messages during bulk sync (strings are delimited by the grave accent symbol "`" with decimal code 96)

Other codes
Connection management actions
[0xFA]

action# error; the code is sent when the server is not able to re-establish the connection from the given action#; the browser must re-initialize the connection w/o action# using OPEN;

[0xFC], string:"[project_id]"

the server has changed the project; project_id is in the form "e-mail/home-relative-location";

[0xFD, ms]

the browser MUST wait for [ms] miliseconds; during this time actions must not be sent to the server (but they can be cached for sending them later); the 0xFD code is send when too many users are connected; if the browser ignores this wait request and sends an action before the waiting time expired, the client will be disconnected (as a security measure)

[0xFE]

invalid access token specified or other security error occurred (the browser MUST redirect to the login page); if the client continues to use invalid access tokens, it will be stored in the black list;

Sync max reference action
[0xFF, rMaxReference, bitsCount, bitsValues]

synchronize max used reference as well as the number of predefined lowest bits and their values; e.g., if the server uses even references, it informs the browser to use odd references by sending bitsCount=1 (1 lowest bit) and bitsValues=1 (odd numbers)

Save ball action
[0xBB]

the browser sends this code ("save ball") to ask the server to save the current content of the repository (e.g., the browser sends this after certain period of inactivity); if the server is not able to save (e.g., some web processor is using the given web memory slot), it sends back the same code ("save ball"), thus, informing the browser to re-send the "ball" later

Web calls

Using "jsoncall" calling conventions:

[0xC0, call#], string:"[action_name]/[stringified-json-argument]"

asynchronously call server-side web calls action (if called from the browser) or browser-side web calls action (if called from the server, e.g., by a web processor); call# is just an integer for identifying the call when the return value is synced back (call#==0 can be used to indicate that the return value is not needed)

[0xC1, call#], string:"[stringified-json-result]"

send back the return value

Using "webmemcall" calling conventions:

[0xC0, rObject], string:"[action_name]"

asynchronously call server-side web calls action (if called from the browser) or browser-side web calls action (if called from the server, e.g., by a web processor); rObject is a call argument (an object reference in web memory); no return value is expected for "webmemcall" calling conventions;