interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/home/tetron/hack/vos/apps/tutorials/vostut3client.cc

Go to the documentation of this file.
00001 /* Third VOS tutorial.  Local and Remote Vobjects and Messages.
00002 
00003    This tutorial file covers:
00004    - The difference between local and remote Vobjects
00005    - Accessing a remote Vobject
00006    - Creating a message and filling its fields
00007    - Sending a message to another Vobject
00008 
00009    This file (vostut3client.cc) is released into the public domain.  No
00010    restrictions are placed on its use, distribution or inclusion into
00011    other works. */
00012 
00013 #include <vos/vos/vos.hh>
00014 
00015 #ifdef WIN32
00016 #define sleep(x) _sleep(x)
00017 #endif
00018 
00019 using namespace VUtil;
00020 using namespace VOS;
00021 
00022 // You must run this program after running vostut3server.
00023 
00024 int main(int argc, char** argv)
00025 {
00026     std::cout << "VOS Tutorial 3 Client\n\n";
00027 
00028     Site localsite;
00029     localsite.addSiteExtension(new LocalVipSiteExtension());
00030 
00031     // If the server process reports that it is using a different port
00032     // that 4231 then you will need to supply it on the command line.
00033 
00034     std::string siteurl;
00035     if(argc > 1) siteurl = argv[1];
00036     else siteurl = "vip://localhost:4231";
00037 
00038     try {
00039         /* The primary purpose of VOS is to allow transparent access to
00040            Vobjects, whether they are local or remote.  A "local" Vobject
00041            resides in the same process and address space as this application.
00042            It does not involve any sort of network activity (even a
00043            loopback socket) to manipulate a local Vobject.  A "remote"
00044            Vobject is anything which requires some sort of network
00045            activity to access.
00046 
00047            Vobjects are located using URLs.  The URL expresses the
00048            hostname and port of the site the Vobject resides upon,
00049            and the name of the object we want to access.  The static
00050            method findObjectFromRoot() takes care of connecting to the
00051            remote site, getting information about the Vobject and
00052            creating an instance of RemoteVobject which will represent
00053            the Vobject in our application.  */
00054 
00055         vRef<Vobject> primus = Vobject::findObjectFromRoot(siteurl + "/primus");
00056 
00057 
00058         // All the methods we demonstrated in the previous tutorial
00059         // are available.  Compare the following output to the same
00060         // code in the server:
00061         vRef<Site> site = primus->getSite();
00062 
00063         std::cout << "vostut3client: Vobject site name is: " << primus->getSiteName() << "\n";
00064         std::cout << "vostut3client: Vobject URL is: " << primus->getURLstr() << "\n";
00065         std::cout << "vostut3client: Vobject site is: " << site->getURLstr() << "\n";
00066         std::cout << "vostut3client: Our local site is: " << localsite.getURLstr() << "\n";
00067 
00068         std::cout << "vostut3client: Primus is local? " << (primus->isLocal() ? "yes" : "no") << "\n";
00069         std::cout << "vostut3client: Primus is remote? " << (primus->isRemote() ? "yes" : "no") << "\n";
00070 
00071 
00072         /* Vobjects can exchange messages with one another.  One way
00073            to think about a Vobject is as a mailbox: an address which
00074            can send and receive messages intended for a certain part
00075            of your application.  Let's say hello to the "primus"
00076            object.
00077         */
00078 
00079         /* Messages are reference counted and should always be
00080            assigned to a vRef<>.  When assigning a bare pointer to a
00081            smart pointer, you must tell it whether to increment the
00082            reference count or not.  A true value for the second
00083            parameter means increment, a false value means do not
00084            increment.  Normally you supply "true", but when an object
00085            is newly created, its reference count is already set to 1.
00086            Since we want the smart pointer to delete the object when
00087            we are done with it, we must tell vRef<> not to increment
00088            the pointer, so that when it is done it will decrement it
00089            to 0 and actually delete the object.
00090         */
00091         vRef<Message> m(new Message(), false);
00092 
00093         /* It seem odd that we need to say that the message type of a
00094            message is "message" but in fact there are a few different
00095            types of messages with different semantics.  A simple
00096            "message" is sent directly from one Vobject to another.
00097            Other messages types are covered in a later tutorial.
00098         */
00099         m->setType("message");
00100 
00101         // The message is directed to the primus Vobject.  You should
00102         // always use the full URL of the Vobject you are sending to.
00103         m->setTo(primus->getURLstr());
00104 
00105         // The message comes from our local site.
00106         m->setFrom(localsite.getURLstr());
00107 
00108         // The method.  This is the action expressed by this message.
00109         m->setMethod("tutorial:hello");
00110 
00111         /* Now we add some fields.  Fields of a VOS message are
00112            ordered and consist of a key and a value.  The first
00113            parameter is the key, and the second parameter is the value
00114            associated with that key.  Fields are ordered and
00115            distinguished by position, so keys may appear more than
00116            once. */
00117 
00118         m->appendField("unus", "one");
00119         m->appendField("word", "Caesar");
00120         m->appendField("unus", "ichi");
00121         m->appendField("duo", "two");
00122 
00123         /* Send the messages to the "primus" Vobject.  That's it!
00124            Simple!
00125         */
00126         std::cout << "vostut3client: sending message...\n";
00127         primus->sendMessage(m);
00128 
00129         std::cout << "vostut3client: waiting 1 second\n";
00130         sleep(1);
00131 
00132         /* The following exceptions may be emitted by
00133            Vobject::findObjectFromRoot():
00134         */
00135     } catch(NoSuchSiteError e) {
00136         // The site we wanted to access doesn't exist (we couldn't connect to it)
00137         std::cout << "Error!  " << e.what() << "\n";
00138 
00139     } catch(NoSuchObjectError e) {
00140         // The site exists, but there is no object by that name
00141         std::cout << "Error!  " << e.what() << "\n";
00142 
00143     } catch(AccessControlError e) {
00144         // We are not permitted to access this Vobject
00145         std::cout << "Error!  " << e.what() << "\n";
00146 
00147     } catch(RemoteError e) {
00148         // Something else bad happened, perhaps a remote site took too
00149         // long to reply and we timed out and gave up.
00150         std::cout << "Error!  " << e.what() << "\n";
00151 
00152     } catch(BadURLError e) {
00153         // We couldn't parse the URL!
00154         std::cout << "Error!  " << e.what() << "\n";
00155     }
00156     std::cout << "vostut3client: done\n";
00157     // We've either sent off our message or handled an exception, so
00158     // let the program run to completion...
00159 }