
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