GizmoDistribution

server.cpp

Server example application.

This example illustrates how to create a simple riority based distributed server using GizmoDistribution. The server instance class inherits the gzDistServerInterface class and implements the virtual callback interface. By running (starting and stopping) a few server applications with different priorities (given on the command line) the behaviour of the priority based distributed server support can be observed.

The source code can also be found in the examples directory of the GizmoDistribution installation.

.

00001 //*****************************************************************************
00002 // File         : server.cpp
00003 // Module       : server
00004 // Description  : server (example application)
00005 // Author       : Anders Sandblad       
00006 // Product      : GizmoDistribution
00007 //      
00008 // Copyright © 2004- Saab Training Systems AB, Sweden
00009 //          
00010 // NOTE:    GizmoDistribution is a toolkit that is used to implement
00011 //          network distributed objects and events in C++
00012 //
00013 //
00014 // Revision History...                          
00015 //                                  
00016 // Who  Date    Description                     
00017 //                                  
00018 // XAA  031030  Created file    
00019 //
00020 //*****************************************************************************
00021 
00022 // Includes
00023 #include "gzDistributionLibrary.h"
00024 
00025 //-----------------------------------------------------------------------------
00026 
00027 // Message receiver
00028 class MessageReceiver : public gzMessageReceiverInterface
00029 {
00030     public:
00031     
00032         gzVoid onMessage(const gzString& sender, gzMessageLevel level, const char* message);
00033 
00034 };
00035 
00036 // Message receiver callback
00037 gzVoid MessageReceiver::onMessage(const gzString& sender, gzMessageLevel level, const char* message)
00038 {
00039     gzString output;
00040     
00041     if (level >= GZ_MESSAGE_NOTICE)
00042     {
00043         if (level >= GZ_MESSAGE_ASSERT)
00044         {
00045             output.format("[ASSERT] %s\n", message);
00046         } // endif
00047         if (level >= GZ_MESSAGE_FATAL)
00048         {
00049             output.format("[FATAL] %s\n", message);
00050         } // endif
00051         else if (level >= GZ_MESSAGE_WARNING)
00052         {
00053             output.format("[WARNING] %s\n", message);
00054         } // endif
00055         else
00056         {
00057             output.format("%s\n", message);
00058         } // endelse
00059 
00060         printf((const char*)output);
00061 
00062     } // endif
00063     else
00064     {
00065         output.format("%s\n", message);
00066     } // endelse
00067 
00068     #ifdef GZ_DEBUG     
00069         #ifdef GZ_WIN32
00070             gzString debug;
00071             debug.format("%s: %s", (const char*)sender, (const char*)output);
00072             OutputDebugStringA((const char*)debug); // WIN32 debug output
00073         #else
00074             // ??
00075         #endif
00076     #endif
00077 
00078 }
00079 
00080 
00081 //-----------------------------------------------------------------------------
00082 
00083 // Simple example server instance 
00084 class SimpleServer: public gzDistServerInterface, public gzThread
00085 {
00086     public:
00087 
00088         explicit SimpleServer(gzDistServerPriority priority);
00089         
00090         virtual ~SimpleServer();
00091 
00092 
00093         //----- server callbacks -----
00094 
00095         gzVoid onStatus(gzDistServerStatus status);
00096 
00097         gzVoid onNewInstance(const gzDistInstanceID& id);
00098 
00099         gzVoid onRemoveInstance(const gzDistInstanceID& id, gzDistServerRemoveReason reason);
00100 
00101         gzVoid onActiveInstance(const gzDistInstanceID& id);
00102 
00103 
00104         //----- thread -----
00105         
00106         gzVoid process();
00107 
00108 
00109     private:
00110 
00111         gzDistServerStatus m_status;
00112 
00113 
00114 
00115 }; // SimpleServer
00116 
00117 
00118 // Constructor
00119 SimpleServer::SimpleServer(gzDistServerPriority priority)
00120  :  gzDistServerInterface("example", priority), // The function ID of the server is "example"
00121     m_status(GZ_DIST_SERVER_STATUS_IDLE)
00122 {
00123 }
00124 
00125 
00126 // Destructor
00127 SimpleServer::~SimpleServer()
00128 {
00129     if (isRunning())
00130     {
00131         gzThread::stop(TRUE);
00132     }
00133 }
00134 
00135 
00136 // Local server status callback
00137 gzVoid SimpleServer::onStatus(gzDistServerStatus status)
00138 {
00139     m_status = status;
00140 
00141     switch (status)
00142     {
00143         case GZ_DIST_SERVER_STATUS_ACTIVE:
00144         {
00145             // Start the thread when activated
00146             if (!isRunning())
00147             {
00148                 gzThread::run();
00149             }
00150         }
00151         break;
00152 
00153         default:
00154         {
00155             // Stop the thread when not active
00156             if (isRunning())
00157             {   
00158                 gzThread::stop(TRUE);
00159             }
00160         }
00161         break;
00162     }
00163 }
00164 
00165 
00166 // New remote server instance callback
00167 gzVoid SimpleServer::onNewInstance(const gzDistInstanceID& id)
00168 {
00169     GZMESSAGE("SimpleServer", GZ_MESSAGE_NOTICE, "New instance: %s", (const char*)id.asString());
00170 }
00171 
00172 
00173 // Remove remote server instance callback
00174 gzVoid SimpleServer::onRemoveInstance(const gzDistInstanceID& id, gzDistServerRemoveReason reason)
00175 {
00176     switch (reason)
00177     {
00178         case GZ_DIST_SERVER_REMOVE_SHUTDOWN:
00179             GZMESSAGE("SimpleServer", GZ_MESSAGE_NOTICE, "Instance shutdown: %s", (const char*)id.asString());
00180             break;
00181             
00182         case GZ_DIST_SERVER_REMOVE_TIMEOUT:
00183             GZMESSAGE("SimpleServer", GZ_MESSAGE_DEBUG, "Instance timeout: %s", (const char*)id.asString());
00184             break;      
00185     }
00186 
00187 }
00188 
00189 
00190 // Actice remote server instance callback
00191 gzVoid SimpleServer::onActiveInstance(const gzDistInstanceID& id)
00192 {
00193     if (id.isNull())
00194     {
00195         GZMESSAGE("SimpleServer", GZ_MESSAGE_NOTICE, "There is no active server instance");
00196     }
00197     else
00198     {
00199         GZMESSAGE("SimpleServer", GZ_MESSAGE_NOTICE, "Active instance: %s", (const char*)id.asString());
00200     }
00201 }
00202 
00203 
00204 // Example server thread
00205 gzVoid SimpleServer::process()
00206 {   
00207     while (!isStopping())
00208     {
00209         gzSleep(GZ_SLEEP_SECOND);
00210 
00211         if (m_status == GZ_DIST_SERVER_STATUS_ACTIVE)
00212         {
00213             GZMESSAGE("SimpleServer", GZ_MESSAGE_NOTICE, "I am the server");
00214         }
00215     }
00216 }
00217 
00218 
00219 //-----------------------------------------------------------------------------
00220 
00221 // Get help from command line
00222 gzBool getHelp(int argc, char* argv[])
00223 {
00224     for (int i = 1; i < argc; i++)
00225     {
00226         gzString arg = gzString(argv[i]).toLower();
00227 
00228         if (arg == "-help") return TRUE;
00229     
00230         if (arg == "-h") return TRUE;
00231     
00232         if (arg == "-?") return TRUE;
00233     
00234     }
00235 
00236     return FALSE;
00237 
00238 }
00239 
00240 
00241 // Get priority from command line
00242 gzDistServerPriority getPriority(int argc, char* argv[])
00243 {
00244     for (int i = 1; i < argc; i++)
00245     {
00246         gzString arg = gzString(argv[i]).toLower();
00247 
00248         if (arg == "-never")
00249         {
00250             printf("\nServer priority: never\n\n");
00251             return GZ_DIST_SERVER_PRIO_NEVER;
00252         }
00253         else if (arg == "-verylow")
00254         {
00255             printf("\nServer priority: very low\n\n");
00256             return GZ_DIST_SERVER_PRIO_VERY_LOW;
00257         }
00258         else if (arg == "-low")
00259         {
00260             printf("\nServer priority: low\n\n");
00261             return GZ_DIST_SERVER_PRIO_LOW;
00262         }
00263         else if (arg == "-normal")
00264         {
00265             printf("\nServer priority: normal\n\n");
00266             return GZ_DIST_SERVER_PRIO_NORMAL;
00267         }
00268         else if (arg == "-high")
00269         {
00270             printf("\nServer priority: high\n\n");
00271             return GZ_DIST_SERVER_PRIO_HIGH;
00272         }
00273         else if (arg == "-veryhigh")
00274         {
00275             printf("\nServer priority: very high\n\n");
00276             return GZ_DIST_SERVER_PRIO_VERY_HIGH;
00277         }
00278         else if (arg == "-max")
00279         {
00280             printf("\nServer priority: max\n\n");
00281             return GZ_DIST_SERVER_PRIO_MAX;
00282         }
00283 
00284     }
00285 
00286     printf("\nServer priority: normal\n\n");
00287     return GZ_DIST_SERVER_PRIO_NORMAL;
00288 
00289 }
00290 
00291 
00292 // Get message level from command line
00293 gzMessageLevel getMessageLevel(int argc, char* argv[])
00294 {
00295     for (int i = 1; i < argc; i++)
00296     {
00297         gzString arg = gzString(argv[i]).toLower();
00298 
00299         if (arg == "-memdebug")
00300         {
00301             return GZ_MESSAGE_MEM_DEBUG;
00302         }
00303         else if (arg == "-debug")
00304         {
00305             return GZ_MESSAGE_DEBUG;
00306         }
00307         else if (arg == "-notice")
00308         {
00309             return GZ_MESSAGE_NOTICE;
00310         }
00311         else if (arg == "-warning")
00312         {
00313             return GZ_MESSAGE_WARNING;
00314         }
00315         else if (arg == "-fatal")
00316         {
00317             return GZ_MESSAGE_FATAL;
00318         }
00319 
00320     }
00321 
00322     #ifdef GZ_DEBUG
00323         return GZ_MESSAGE_DEBUG;
00324     #else
00325         return GZ_MESSAGE_NOTICE;
00326     #endif
00327 
00328 }
00329 
00330 
00331 // Print help
00332 gzVoid printHelp()
00333 {
00334     printf("Command line argumets:\n\n");
00335 
00336     printf("  Priority levels:\n");
00337     printf("    -never\n");
00338     printf("    -verylow\n");
00339     printf("    -low\n");
00340     printf("    -normal (default)\n");
00341     printf("    -high\n");
00342     printf("    -veryhigh\n");
00343     printf("    -max\n\n");
00344 
00345     printf("  Message output levels:\n");
00346     printf("    -debug\n");
00347     printf("    -notice (default)\n");
00348     printf("    -warning\n\n");
00349 
00350     printf("  Help (this text):\n");
00351     printf("    -help\n\n");
00352 
00353 }
00354 
00355 
00356 //-----------------------------------------------------------------------------
00357 
00358 // Application entry point
00359 int main(int argc, char* argv[])
00360 {
00361     // Print example info
00362     printf("\nThis is a GizmoSDK example application that illustrates how to create\n");
00363     printf("a simple priority based distributed server using GizmoDistribution.\n\n");
00364     printf("(c) 2004- Saab Training Systems AB, Sweden\n\n");
00365 
00366     // Look for help arg on the command line
00367     if ( getHelp(argc, argv) )
00368     {
00369         printHelp();
00370         return 0;
00371     }
00372 
00373     // Add message receiver (with level from command line)
00374     MessageReceiver messageReceiver;
00375     gzMessage::setMessageLevel( getMessageLevel(argc, argv) );
00376     gzMessage::addMessageReceiver(&messageReceiver);
00377     
00378     // Create manager
00379     gzDistManagerPtr manager = gzDistManager::getManager(TRUE);
00380     
00381     // Setup session channel
00382     gzDistRemoteChannel* sessionChannel = new gzDistRemoteChannel;
00383     gzDistTransportUDP* sessionTransport = new gzDistTransportUDP;
00384     sessionTransport->createMulticast(gzSocketAddress(gzHostAddress(234,56,78,90), 8888));
00385     sessionChannel->setTransport(sessionTransport);
00386     
00387     // Setup server channel
00388     gzDistRemoteChannel* serverChannel = new gzDistRemoteChannel;
00389     gzDistTransportUDP* serverTransport = new gzDistTransportUDP;
00390     serverTransport->createMulticast(gzSocketAddress(gzHostAddress(234,56,78,90), 9999));
00391     serverChannel->setTransport(serverTransport);
00392 
00393     // Start manager
00394     manager->start(sessionChannel, serverChannel);
00395 
00396     // Create the server instance (with priority from the command line)
00397     SimpleServer server( getPriority(argc, argv) );
00398 
00399     printf("Hit return key to quit!\n\n\n");
00400 
00401     // Install the instance
00402     server.install();
00403     
00404     // Wait for return
00405     getchar();
00406 
00407     // Uninstall the instance
00408     server.uninstall();
00409 
00410     // Shutdown remote distribution
00411     manager->shutDown();
00412     manager = NULL;
00413 
00414     // Remove message receiver
00415     gzMessage::removeMessageReceiver(&messageReceiver);
00416 
00417     return 0;
00418 
00419 }
00420 

Documentation for GizmoDistribution generated at Wed Feb 20 11:59:21 2008 by   Saab Training Systems AB, ¸ (c) 2003-and beyond