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

/home/tetron/hack/vos/apps/tutorials/vostut3server.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    - Setting up a message handler for messages
00005    - Accessing message fields
00006 
00007    This file (vostut3server.cc) is released into the public domain.  No
00008    restrictions are placed on its use, distribution or inclusion into
00009    other works.
00010 */
00011 
00012 #include <vos/vos/vos.hh>
00013 
00014 using namespace VUtil;
00015 using namespace VOS;
00016 
00017 #ifdef WIN32
00018 #define sleep _sleep
00019 #endif
00020 
00021 // You must run this program before running vostut3client.
00022 
00023 
00024 /* This tutorial demonstrates how to handle incoming messages.  The
00025    following class provides a method to be called when a message is
00026    received.  Message handler objects must derive from the MetaObject (discussed later)
00027    or VobjectExtension class.
00028  */
00029 class TutorialMessageHandler : public VobjectExtension
00030 {
00031 private:
00032     vRef<Vobject> primus;
00033 public:
00034     TutorialMessageHandler(Vobject* p);
00035     void handleSampleMessage(Message* msg);
00036 };
00037 
00038 
00039 int main(int argc, char** argv)
00040 {
00041     std::cout << "VOS Tutorial 3 Server\n\n";
00042 
00043     Site localsite;
00044     localsite.addSiteExtension(new LocalVipSiteExtension());
00045     localsite.setDefaultPolicy("core:accept-all");
00046 
00047     vRef<Vobject> primus = localsite.createVobjectA("primus");
00048 
00049     /* Since primus was created on localsite, calling getSite() on
00050        primus just gives us back localsite.  Compare the output of
00051        following to the output of the same code on the client.
00052      */
00053     vRef<Site> site = primus->getSite();
00054     std::cout << "vostut3server: Vobject site name is: " << primus->getSiteName() << "\n";
00055     std::cout << "vostut3server: Vobject URL is: " << primus->getURLstr() << "\n";
00056     std::cout << "vostut3server: Vobject site is: " << site->getURLstr() << "\n";
00057     std::cout << "vostut3server: Our local site is: " << localsite.getURLstr() << "\n";
00058 
00059     // The difference between local and remote objects is discussed in
00060     // vostut3client.
00061     std::cout << "vostut3server: Primus is local? " << (primus->isLocal() ? "yes" : "no") << "\n";
00062     std::cout << "vostut3server: Primus is remote? " << (primus->isRemote() ? "yes" : "no") << "\n";
00063 
00064     /* Create our message handler object, passing it a pointer to
00065        primus.
00066     */
00067     TutorialMessageHandler* tmh = new TutorialMessageHandler(primus);
00068 
00069     /* Register a message handler for primus by adding the message handler
00070        as an extension to this vobject.  In this case, when a message
00071        with method "tutorial:hello" is delivered to primus, it will
00072        call the handleSampleMessage() method on the object "tmh" that
00073        we have created.
00074      */
00075     primus->getVobjectBase()->addVobjectExtension(tmh);
00076 
00077     /* Now idle.  When we receive a message, the message handlers will
00078        called in a separate thread. */
00079     while(true) sleep(1000);
00080 }
00081 
00082 
00083 TutorialMessageHandler::TutorialMessageHandler(Vobject* p)
00084 {
00085     /* When assigning a bare pointer to a smart pointer, you must tell
00086        it whether to increment the reference count or not.  A true
00087        value for the second parameter means increment, a false value
00088        means do not increment.  Either way the reference count is
00089        still decremented as normal when the smart pointer goes away.
00090        Generally you want it to increment the count (with one common
00091        exception described in vostut3client.cc).
00092     */
00093     primus.assign(p, true);
00094 
00095     /* We only want this code to run once, so we surround it with the "init" guards.
00096        This adds an entry in the message handler table that indicates that message
00097        with the "tutorial:hello" method are passed to the TutorialMessageHandler::handleSampleMessage
00098        method if the target vobject has a VobjectExtension or MetaObject of type
00099        "TutorialMessageHandler".
00100      */
00101     static bool init = true;
00102     if(init) {
00103         init = false;
00104         VobjectBase::addMessageHandler("tutorial:hello", &TutorialMessageHandler::handleSampleMessage);
00105     }
00106 }
00107 
00108 void TutorialMessageHandler::handleSampleMessage(Message* msg)
00109 {
00110     // First print out the message
00111     std::cout << "vostut3server: "
00112               << primus->getSiteName()
00113               << " received a message:\n"
00114               << msg->getFormattedString() << "\n";
00115 
00116     // Messages have a number of standard fields.  The "method"
00117     // field indicates the action the sender is expressing.
00118     std::cout << "Method is: " << msg->getMethod() << "\n";
00119 
00120     // Another standard field is "from".  There is of
00121     // course a "to" field as well :-)
00122     std::cout << "vostut3server: The object " << msg->getFrom() << " said hello to us!  Isn't that nice.\n";
00123 
00124     try {
00125         /* We can access a particular field using its name.  If no
00126            field by that name is present, then a NoSuchFieldError
00127            exception will be thrown.  You cannot access the fixed to,
00128            from, method, etc fields this way (use getTo(), getFrom(),
00129            getMethod() instead). */
00130 
00131         std::cout << "vostut3server: The word of the day is \""
00132              << msg->getField("word")->value << "\"\n";
00133 
00134     } catch(NoSuchFieldError) {
00135         // If we ask for a certain field on a message and it is not present,
00136         // this exception will be thrown
00137         std::cout << "vostut3server: Oops, no \"word\" field is present, no word of the day for us.\n";
00138     }
00139 
00140     std::cout << "vostut3server: The fields in this message are:\n";
00141 
00142     /* The fields in a message are also ordered and so we can iterate
00143        over them:
00144     */
00145     for(int i = 0; i < msg->numFields(); i++) {
00146         std::cout << " " << i << "  " << msg->getField(i)->key
00147                   << "=\""
00148                   << msg->getField(i)->value
00149                   << "\"\n";
00150     }
00151 }