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/corelibs/vos/vos.hh> 00014 00015 // You must run this program after running vostut3server. 00016 00017 int main(int argc, char** argv) 00018 { 00019 cout << "VOS Tutorial 3 Client\n\n"; 00020 00021 LocalSocketSite localsite(&NoAccessControl::static_); 00022 00023 // If the server process reports starting at a different port that 00024 // 4231 then you will need to supply it on the command line. 00025 00026 string siteurl; 00027 if(argc > 1) siteurl = argv[1]; 00028 else siteurl = "vop://localhost:4231"; 00029 00030 try { 00031 /* The primary purpose of VOS is to allow transparent access to 00032 Vobjects, whether they are local or remote. A "local" Vobject 00033 resides the same process and address space as this application. 00034 It does not involve any sort of network activity (even a 00035 loopback socket) to manipulate a local Vobject. A "remote" 00036 Vobject is anything which requires some sort of network 00037 activity to access. 00038 00039 Vobjects are accessed using URLs. The URL expresses the 00040 hostname and port of the site this Vobject resides upon, 00041 and the name of the object we want to access. The static 00042 method findObjectFromRoot() takes care of connecting to the 00043 remote site, getting information about the Vobject and 00044 creating an instance of RemoteVobject which will represent 00045 the Vobject in our application. */ 00046 00047 vRef<Vobject> primus = Vobject::findObjectFromRoot(siteurl + "/primus"); 00048 00049 00050 // All the methods we demonstrated in the previous tutorial 00051 // are available 00052 00053 cout << "vostut3client: Vobject site name is: " << primus->getName() << "\n"; 00054 cout << "vostut3client: Vobject URL is: " << primus->getURL().getString() << "\n"; 00055 vRef<Site> site = primus->getSite(); 00056 cout << "vostut3client: Vobject site is: " << site->getURL().getString() << "\n"; 00057 cout << "vostut3client: Our local site is: " << localsite.getURL().getString() << "\n"; 00058 00059 cout << "vostut3client: Primus is local? " << primus->isLocal() << "\n"; 00060 cout << "vostut3client: Primus is remote? " << primus->isRemote() << "\n"; 00061 00062 00063 /* Vobjects can exchange messages with one another. One way 00064 to think about a Vobject is as a mailbox: an address which 00065 can send and receive messages intended for a certain part 00066 of your application. Let's say hello to the "primus" 00067 object. 00068 */ 00069 00070 // Messages are reference counted and should always be 00071 // assigned to a vRef<>. 00072 vRef<Message> m = new Message(); 00073 00074 /* This may seem a bit odd, but there are actually several 00075 different types of messages. A "message" type is the 00076 simplest, being sent directly from one Vobject to another. 00077 Other messages types are processed differently (these are 00078 discussed in a later tutorial.) */ 00079 00080 m->setType("message"); 00081 00082 // The message is directed to the primus Vobject. You should 00083 // always use the full URL of the Vobject you are sending to. 00084 m->setTo(primus->getURL().getString()); 00085 00086 // The message comes from our local site. 00087 m->setFrom(localsite.getURL().getString()); 00088 00089 // The method. This is the action expressed by this message. 00090 m->setMethod("tutorial:hello"); 00091 00092 /* Now we add some fields. Fields of a VOS message are 00093 ordered and consist of a key and a value. The first 00094 parameter of the insertField() messages is the position to 00095 insert the new field in to; "-1" means to append the field 00096 to the end. The second parameter is the key, and the third 00097 parameter is the value associated with that key. Since 00098 fields are distinguished by position, keys may appear more 00099 than once. */ 00100 00101 m->insertField(-1, "unus", "one"); 00102 m->insertField(-1, "word", "Caesar"); 00103 m->insertField(-1, "unus", "ichi"); 00104 m->insertField(-1, "duo", "two"); 00105 00106 // Send the messages to the "primus" Vobject. That's it! 00107 // Simple! 00108 00109 cout << "vostut3client: sending message...\n"; 00110 primus->sendMessage(&m); 00111 00112 00113 // Most applications required a run loop which calls 00114 // flushIncomingBuffers() periodically. For this simple 00115 // client we can let the program run to completion. 00116 00117 00118 // The following exceptions may be emitted by Vobject::findObjectFromRoot(): 00119 00120 } catch(Vobject::NoSuchSiteError e) { 00121 // The site we wanted to access doesn't exist (we couldn't connect to it) 00122 cout << "Error! " << e.what() << "\n"; 00123 00124 } catch(Vobject::NoSuchObjectError e) { 00125 // The site exists, but there is no object by that name 00126 cout << "Error! " << e.what() << "\n"; 00127 00128 } catch(Vobject::AccessControlError e) { 00129 // We are not permitted to access this Vobject 00130 cout << "Error! " << e.what() << "\n"; 00131 00132 } catch(Vobject::RemoteError e) { 00133 // Something else bad happened, perhaps a remote site took too 00134 // long to reply and we timed out and gave up. 00135 cout << "Error! " << e.what() << "\n"; 00136 00137 } catch(URL::BadURLError e) { 00138 // We couldn't parse the URL! 00139 cout << "Error! " << e.what() << "\n"; 00140 } 00141 }