/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 }