Usage

=Using VAST=

Using VAST is simple. For the C++ code, you just need to include "VASTVerse.h", the factory class for VAST, and optionally "VASTsim.h", if you also want to use some existing utility to read parameters.

VAST defines certain base data types and base classes (you can refer to "/common/VASTTypes.h for details). For example, the following are the most basic ones:

code // hostID (globally unique) or nodeID (unique within each world) typedef uint64_t id_t;

// timestamp type, stores the timestamp obtained from system typedef uint32_t timestamp_t;

// the number of layers in the overlay (0 - 65535) typedef uint16_t layer_t;

// position inside the virtual world, consists of x, y, z coordinates class Position

// an area, can be either a circle (center & radius), or a rectangle (center, width, and height) class Area

// IP address, consisting of host and port class IPaddr

// a VAST node's host address, consisting of hostID, and IP address class Addr

// a VAST node, consisting of its hostID, last time of access, AOI, and host address class Node

// a subscription, consisting of hostID, subscriptionID, layer, last time of use, AOI, and the relay class Subscription

// a user message sent between nodes, consisting of a message type, priority number, data, and targets class Message

code

The easiest way to create an instance of VAST, is to call the following function in the VASTVerse class (the factory class for VAST nodes): code bool createVASTNode (const IPaddr &gateway, Area &area, layer_t layer); code

where gateway refers to the IP address of the Gateway node, area refers to the initial subscribed area, and layer refers to which layer to subscribe (VAST supports from 1 to 65,535 different user-defined layer numbers). A VAST node will only receive publications fall within its subscribed area, but also at the same layer. Once a subscription request is made, the application can just keep calling the following function to obtain a pointer to the created VAST node (NULL is returned before the VAST node has joined successfully).

code VAST *getVASTNode ; code

Once the VAST node is obtained, the application can called the following two simple functions to initialize:

code bool join (const IPaddr &gateway);

bool subscribe (Area &area, layer_t layer); code

join adds the VAST node to an existing P2P network of nodes, whose first node (the gateway) is specified in the IP address parameter, so that subscriptions can be performed. This 'gateway' can be the same as the one used in createVASTNode, or a different one. The reason is that a VAST node such that it can switch the 'gateway' while running, effectively joining into a different virtual space (and perform new subscriptions subsequently). Application can then subscribe to an area at a specific layer. The application then needs to call the following to make sure a subscription ID is obtained, before moving on. code id_t getSubscriptionID ; code

Finally, to interact within the P2P network, the application calls one of the following: code Area *move (id_t subID, Area &aoi);

bool publish (Area &area, layer_t layer, Message &message);

vector& list ;

int send (Message &message); code move basically changes the subscribed area for the given subscription ID. publish sends a message to an area at a specific layer. and send sends a custom message to one or more nodes stored within the Message's targets.

**Socket Communications**
Direct socket communications are also provided by VAST if the application needs to use them. You can pass an IP/port info to open a TCP connection to a remote server (with optional SSL encryption), and to send and receive any byte string once the connection is opened. The four main functions to use are:

code // open a new socket specified given in the IPaddr, a socket id is returned id_t openSocket (IPaddr &ip_port, bool is_secure = false);

// send a message of a given size to the socket (based on its id) bool sendSocket (id_t socket, const char *msg, size_t size);

// receive messages, by passing in references to receive socket id and message size // NULL is received is no more messages char *receiveSocket (id_t &socket, size_t &size);

// close up an existing socket bool closeSocket (id_t socket);

// check whether a given socket is still connected bool isSocketConnected (id_t socket);

code

Sample Program
We use the sample code in "/Demo/demo_console/demo_console.cpp" as a skeleton to explain what a minimal VAST-based program might look like. Note that this is only a skeleton, you will want to fill in other parts to suit your particular needs. The sample serves to provide an idea of how to initialize a VAST node, and how the main loop should run VAST.

code
 * 1) include "VASTVerse.h"
 * 2) include "VASTsim.h"


 * 1) define VAST_EVENT_LAYER   1                   // layer ID for sending events
 * 2) define VAST_UPDATE_LAYER  2                   // layer ID for sending updates

using namespace Vast; using namespace std;

int main (int argc, char *argv[]) {   VASTPara_Net    netpara;              // network parameters NodeState      state     = ABSENT;   // the join state of this node Area           aoi;                  // my AOI (with center as current position) Addr           gateway;              // address for gateway

VASTVerse *    world     = NULL; VAST *         self      = NULL; id_t           sub_no    = 0;        // subscription # for my client (peer)

// store default gateway address string str ("127.0.0.1:1037"); gateway = *VASTVerse::translateAddress (str);

// list of entry points vector entries;

// initialize network parameters and entry points (stored in netpara) entries.push_back (gateway.publicIP);

// create VAST node factory world = new VASTVerse (entries, &netpara, NULL); world->createVASTNode (gateway.publicIP, aoi, VAST_EVENT_LAYER);

bool finished = false;

// record beginning of main loop while (!finished) {       if (state != JOINED) {           if ((self = world->getVASTNode ) != NULL) {               sub_no = self->getSubscriptionID ; state = JOINED; }       }

else {           // obtain input from user, will store inside 'aoi' getInput ; self->move (sub_no, aoi); }

// perform some per-second tasks

// process incoming message and perform routine tasks world->tick ;

// sleep a little if there's unused time }

// depart self->leave ; world->destroyVASTNode (self);

delete world;

return 0; }

code