00001 /*------------------------------------------------------------------------------ 00002 Name: xmlBlaster/demo/c++/MultiConnectDemo.cpp 00003 Project: xmlBlaster.org 00004 Comment: C++ client example 00005 Author: Marcel Ruff 00006 ------------------------------------------------------------------------------*/ 00007 #include <client/XmlBlasterAccess.h> 00008 #include <util/Global.h> 00009 #include <vector> 00010 00011 using namespace std; 00012 using namespace org::xmlBlaster::util; 00013 using namespace org::xmlBlaster::util::qos; 00014 using namespace org::xmlBlaster::util::dispatch; 00015 using namespace org::xmlBlaster::client; 00016 using namespace org::xmlBlaster::client::qos; 00017 using namespace org::xmlBlaster::client::key; 00018 00027 class SpecificCallback : public I_Callback, public I_ConnectionProblems 00028 { 00029 private: 00030 const string ME; 00031 I_Log& log_; 00032 public: 00033 SpecificCallback(const GlobalRef global) : ME(global->getInstanceName()), 00034 log_(global->getLog("MultiConnectDemo")) 00035 {} 00036 00040 string update(const string& sessionId, UpdateKey& updateKey, 00041 const unsigned char* content, 00042 long contentSize, UpdateQos& updateQos) 00043 { 00044 string contentStr(reinterpret_cast<char *>(const_cast<unsigned char *>(content)), contentSize); 00045 log_.info(ME, "Received update message with secret sessionId '" + sessionId + "':" + 00046 updateKey.toXml() + 00047 "\n content=" + contentStr + 00048 updateQos.toXml()); 00049 return ""; 00050 } 00051 00052 bool reachedAlive(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00053 { 00054 log_.info(ME, "reconnected"); 00055 return true; 00056 } 00057 00058 void reachedDead(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00059 { 00060 log_.info(ME, "lost connection"); 00061 } 00062 00063 void reachedPolling(StatesEnum /*oldState*/, I_ConnectionsHandler* /*connectionsHandler*/) 00064 { 00065 log_.info(ME, "going to poll modus"); 00066 } 00067 }; 00068 00069 00082 class MultiConnectDemo 00083 { 00084 private: 00085 string ME; 00086 Global& global_; 00087 I_Log& log_; 00089 public: 00090 MultiConnectDemo(Global& glob) : ME("MultiConnectDemo"), global_(glob), 00091 log_(glob.getLog("MultiConnectDemo")) {} 00092 00093 virtual ~MultiConnectDemo() {} 00094 00095 void execute() 00096 { 00097 const int NUM_CONN = global_.getProperty().get("numConn", 10); 00098 long sleepMillis = global_.getProperty().get("sleep", 1000L); 00099 try { 00100 vector<XmlBlasterAccessRef> connVec; // Holding all connections to xmlBlaster 00101 // Connect 5 times to xmlBlaster 00102 for (int i=0; i<NUM_CONN; i++) { 00103 string instanceName = string("connection-") + lexical_cast<std::string>(i); 00104 Property::MapType propMap; 00105 propMap["session.name"] = instanceName; // Set a unique login name 00106 GlobalRef globalRef = Global::getInstance().createInstance(instanceName, &propMap); 00107 connVec.push_back(XmlBlasterAccessRef(new XmlBlasterAccess(globalRef))); 00108 00109 SpecificCallback* cbP = new SpecificCallback(globalRef); 00110 //connVec[i]->initFailsafe(cbP); 00111 ConnectQos qos(*globalRef); 00112 ConnectReturnQos retQos = connVec[i]->connect(qos, cbP); 00113 log_.info(ME, "Successfully connected to xmlBlaster as " + 00114 retQos.getSessionQos().getSessionName()->getAbsoluteName()); 00115 } 00116 00117 // Subscribe 5 times 00118 for (int i=0; i<NUM_CONN; i++) { 00119 SubscribeKey subKey(connVec[i]->getGlobal()); 00120 subKey.setOid("MultiConnectDemo"); 00121 SubscribeQos subQos(connVec[i]->getGlobal()); 00122 log_.info(ME, "Subscribing to xmlBlaster"); // + subKey.toXml() + 00123 SubscribeReturnQos subRetQos = connVec[i]->subscribe(subKey, subQos); 00124 log_.info(ME, "Successfully subscribed to xmlBlaster: " + subRetQos.getSubscriptionId()); 00125 } 00126 00127 // Publish a message with the oid 'MultiConnectDemo' 00128 // all subscribers should receive it 00129 PublishQos publishQos(connVec[0]->getGlobal()); 00130 PublishKey publishKey(connVec[0]->getGlobal()); 00131 publishKey.setOid("MultiConnectDemo"); 00132 MessageUnit msgUnit(publishKey, string("Hi"), publishQos); 00133 log_.info(ME, "Publishing to xmlBlaster"); 00134 PublishReturnQos pubRetQos = connVec[0]->publish(msgUnit); 00135 log_.info(ME, "Successfully published to xmlBlaster: " + pubRetQos.getKeyOid()); 00136 try { 00137 log_.info(ME, "Sleeping now for " + lexical_cast<string>(sleepMillis) + " msec ..."); 00138 org::xmlBlaster::util::thread::Thread::sleep(sleepMillis); 00139 } 00140 catch(const XmlBlasterException &e) { 00141 log_.error(ME, e.toXml()); 00142 } 00143 00144 // Erase the topic 00145 EraseKey eraseKey(connVec[0]->getGlobal()); 00146 eraseKey.setOid("MultiConnectDemo"); 00147 EraseQos eraseQos(connVec[0]->getGlobal()); 00148 log_.info(ME, "Erasing the published message"); 00149 connVec[0]->erase(eraseKey, eraseQos); 00150 00151 // Disconnect all clients 00152 for (int i=0; i<NUM_CONN; i++) { 00153 connVec[i]->disconnect(DisconnectQos(connVec[i]->getGlobal())); 00154 delete connVec[i]->getCallback(); 00155 } 00156 00157 connVec.clear(); 00158 log_.info(ME, "Done, resources are released"); 00159 } 00160 catch (const XmlBlasterException &e) { 00161 log_.error(ME, e.toXml()); 00162 } 00163 } 00164 }; 00165 00166 #include <iostream> 00167 00175 int main(int args, char ** argv) 00176 { 00177 try { 00178 org::xmlBlaster::util::Object_Lifetime_Manager::init(); 00179 Global& glob = Global::getInstance(); 00180 glob.initialize(args, argv); 00181 00182 string intro = "XmlBlaster C++ client " + glob.getReleaseId() + 00183 ", try option '-help' if you need usage informations."; 00184 glob.getLog().info("MultiConnectDemo", intro); 00185 00186 if (glob.wantsHelp()) { 00187 cout << Global::usage() << endl; 00188 cout << endl << "MultiConnectDemo"; 00189 cout << endl << " -sleep Sleep after publishing [1000 millisec]" << endl; 00190 cout << endl << "Example:" << endl; 00191 cout << endl << "MultiConnectDemo -trace true -sleep 2000"; 00192 cout << endl << "MultiConnectDemo -dispatch/connection/delay 10000 -sleep 2000000" << endl << endl; 00193 org::xmlBlaster::util::Object_Lifetime_Manager::fini(); 00194 return 1; 00195 } 00196 00197 MultiConnectDemo hello(glob); 00198 hello.execute(); 00199 } 00200 catch (XmlBlasterException &e) { 00201 std::cerr << "Caught exception: " << e.getMessage() << std::endl; 00202 } 00203 catch (...) { 00204 std::cerr << "Caught exception, exit" << std::endl; 00205 } 00206 org::xmlBlaster::util::Object_Lifetime_Manager::fini(); 00207 return 0; 00208 }